找回密码
 点一下
查看: 1140|回复: 5

[Union Bug]多值多类型对多值多类型的强制类型转换~~替代H2I和I2H的新方案~~

[复制链接]
发表于 2007-12-13 19:37:54 | 显示全部楼层 |阅读模式
算了~~仔细试验之后wc3c那人的理解方法完全不对~~

于是还是删了原来那个帖子~~把我最终的结果重新开个帖子写上来~~

[jass]
globals
      handle H
      integer I
endglobals
[/jass]

[jass]
function Trig_test_Actions takes nothing returns nothing
local integer I
local handle H
set H = GetTriggerUnit()
call BJDebugMsg(I2S(I))
endfunction
[/jass]


这两段代码组合后~~触发动作显示在屏幕上的是什么呢?~0?~

错了~~是触发单位的Handle值~~

很难以置信~~不是嘛?~~

这一问题原是由Wc3c的Troll-Brain发现的~~但他没有正确地了解其原因~~
以下是原帖~~
http://hilton.vs.oiccam.com/showthread.php?t=98230


当全局变量和局部变量同名时~~我们称该全局变量被覆盖~~

然而jass的变量覆盖存在着bug~~

既每执行一次对被覆盖的变量的赋值之后~~当前变量被赋予的值也同时会被无视类型地赋给本函数内所有其余的被覆盖变量~~

也就是说~~在这个函数里~~GetTriggerUnit() 不但被赋给了H~~也被赋给了I~~

我们称这个bug为Union Bug~~是在很多情况下替代以前的Return Bug实现强制类型转换的好方案~~

更多功能见下~~
 楼主| 发表于 2007-12-13 19:41:41 | 显示全部楼层
[trigger]
Sample
    Events
        Player - Player 1 (Red) skips a cinematic sequence
    Conditions
    Actions
        Custom script:   local unit udg_u
        Custom script:   local integer udg_i
        Custom script:   local real udg_r
        Custom script:   local boolean udg_b
        Set u = 圣骑士 0000 <gen>
        Set r = 123.23
        Set b = True
        Set i=1
[/trigger]

以上的动作看似毫无意义~~但如果我们追踪每一步动作中的变量内容变化的话~~就会发现~~

每次对这些被覆盖变量的赋值行为~~都会一并使得其它变量造成影响~~

例如将u设为圣骑士这一句~~同时也将圣骑士的handle值强制赋给了i、r、b~~也就是说~~我们在一句操作中同时达到了将handle强制转换为integer、real和boolean类型的结果!~~

而执行第二句将123.23赋值给r的同时~~也令其它三个被覆盖变量u、i、b的值发生改变~~被强制赋予了123.23这个值~~

下面两句依次类推~~

于是~~利用这个bug~~我们发现了一个极其高效的群体强制数据类型转换的方案~~它甚至不需要调用函数~~


然而~~就像我们知道不能用return bug来强制将handle和real转换为string一样~~我们也不能在这个动作里声明一个类型为string的被覆盖变量~~因为一旦声明~~该string类型的变量也会加入这个变化集群中~~当我们对r赋值的时候~~便会造成real被强制转换为string的结果~~而导致崩溃~~

因此~~在执行这些转换操作的时候~~要特别注意不能将real和handle类型的被覆盖变量和string类型的被覆盖变量放到同一个函数中声明~~而需要分在两个函数~~
回复

使用道具 举报

 楼主| 发表于 2007-12-13 19:55:24 | 显示全部楼层
另一方面~~这一bug仅仅会影响到函数中的被覆盖变量~~而其它类型的变量~~不管是全局变量还是局部变量都不会受其影响~~

这样~~我们就可以用覆盖变量来实现类型转换~~用非覆盖变量来记录转换中间值了~~(因为这里的被覆盖变量本身只会记录最后一个值~~因此我们需要正常变量来记录中间结果~~)

这样~~就能实现在同一函数中同时处理多值对多值~~多类型对多类型的功能~~


用途讲解完毕~~
回复

使用道具 举报

 楼主| 发表于 2007-12-13 20:12:10 | 显示全部楼层
最后~~让我们来分析一下这个bug的成因~~以更好地理解它~~

事实上~~根据所有的测试资料~~我得出了一个非常有说服力的可能解释~~


以下作为我解释Union Bug的假说~~



那就是暴雪在设计jass脚本的时候~~试图让jass模仿其它编程语言中被覆盖变量的功能~~

但是实际实现是失败的~~最终结果~~jass仅仅能够支持让每一个函数拥有一个被覆盖变量~~

而你在同一个函数中声明更多被覆盖变量~~他们占用的仍然是同一个空间~~因此不管你声明的被覆盖变量再多~~它们表现得就像同一个变量一样~~

因此不论你给其中一个被覆盖变量赋何值~~都能从通过其它被覆盖变量将其取出~~


也就是说~~每个函数中所有的被覆盖变量~~之所以表现得形同一人~~其原因正是因为他们都是同一个变量~~只是读取方式不同而已!~~
回复

使用道具 举报

发表于 2007-12-15 08:52:51 | 显示全部楼层
话被您一个人说了.....
回复

使用道具 举报

发表于 2007-12-26 03:08:51 | 显示全部楼层
据测试目前就是这么解释的,不过我不认为这是什么好方案,因为用这个东西会引起程序书写变得很不规范(仅仅jass可以这么乱七八糟的用重名变量)。

老实说H2I我也没感觉是个BUG,本来在其他语言里面强制转换就是个应该具有的功能。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 点一下

本版积分规则

Archiver|移动端|小黑屋|地精研究院

GMT+8, 2024-11-23 02:14 , Processed in 0.362444 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表