| 01-14-2008, 11:57 AM | #1 |
JASS:function I2H takes integer i returns handle return i return null endfunction I've read that this function could bug. And although it is apparently rare, and could not be determined the moment, because it is random. My questions are: - What is the effect of the bug? - Had you ever problems using a function like this: JASS:function I2U takes integer i returns unit return i return null endfunction I supposed that it is the same thing, cause unit type extends handle, but I would like to be sure |
| 01-14-2008, 12:45 PM | #3 |
Effects of the bug are also random. They go from nothing to crashing the game. |
| 01-14-2008, 12:54 PM | #4 |
conclusion: not safe |
| 01-14-2008, 01:45 PM | #5 |
ok thx, so i suppose that the anwser of the second question is: Yes that's the same problem |
| 01-14-2008, 01:59 PM | #6 |
There is no reason nor evidence to think H2I is problematic, and have already seen many maps that use H2I (yet no I2H) massively and are safe. I2H is confirmed to do things like messing up the ref counter thus messing up the handle allocator, it also looks like it is either the catalyst or direct cause to the "DestroyTrigger" bug. I2U is I2H, when we say get rid of I2H it means get rid of any conversion from integer to non-constant handle type. |
| 01-14-2008, 02:03 PM | #7 |
Heres how the bug works: Suppose you have a unit, a footman You set FootmanIndex = H2I(Footman) you call RemoveUnit(Footman). you set Footman = null Now the game recycles the Footman unit index that you have stored in FootmanIndex, and the next handle (or one of the many next) that is created gets the SAME handle index that the Footman has. This will also happen if the footman dies, decays, and gets recycled by the Wc3 engine as well. Now lets say you set Footman = I2U(FootmanIndex). You now have a unit variable that isn't actually a unit, it is a Location! Uh oh! Call GetWidgetLife(Footman). Now you called GetWidgetLife on a Location! This is very bad, and is really unknown to what it specifically does, but it may crash (i never tried it). So the act of calling I2H isnt actually bugged, its a reliable function, but the integer value you pass to I2H being corrupted causes the problems. This problem is easily seen when storing H2I values in gamecache then nulling the handle variable. Then there is no guarantee that the I2H(gamecachevariable) call will give back the correct handle. Theres one method that I know of that prevents this issue. When using H2I, make sure that you store not only the integer value it returns, but also store the handle variable. These must be stored in global variables, not gamecache. This will prevent the Wc3 engine from ever recycling the handle index until you null the handle variable. |
| 01-14-2008, 02:08 PM | #8 | |
Quote:
Sure that case is the user's fault. But that's just the tip of the iceberg regarding I2H , the random stuff it causes to the ref counter is much worse. |
| 01-14-2008, 02:11 PM | #9 |
I've noticed that some handles are more problematic than other, for example, typecasting lightning variables has been a serious issue when I stored and retrieve them. So my best advice: use structs and use gamecache to store the struct index (an integer). This is 100% safe |
| 01-14-2008, 03:00 PM | #10 | |
Quote:
ok i will do that |
| 01-14-2008, 04:15 PM | #12 |
it's not safe cause what will you do when you reach the max index (8190 cause 8191 will cause a crash in a load saved game) |
| 01-14-2008, 04:17 PM | #13 |
True, CSData uses gamecache for index overflow. |
