Cuberite Forum
Weird gcc behavior - Printable Version

+- Cuberite Forum (https://forum.cuberite.org)
+-- Forum: Cuberite (https://forum.cuberite.org/forum-4.html)
+--- Forum: Development (https://forum.cuberite.org/forum-13.html)
+--- Thread: Weird gcc behavior (/thread-629.html)



Weird gcc behavior - xoft - 11-18-2012

I'm trying to figure out what's wrong in FS #265 (unable to place torches in linux debud builds)
http://www.mc-server.org/support/index.php?do=details&task_id=265&project=2

The same problem happens in my virtualboxed ubuntu; I've traced it to be the blockchecking code. However, it's plain weird. I've added some logging and this is what I get. From code (BlockHandler.cpp, cBlockHandler::Check() ):
Code:
bool CanBe = CanBeAt(a_World, a_BlockX, a_BlockY, a_BlockZ);
LOGD("CanBe: %d", CanBe);
if (!CanBe)
{
    if (DoesDropOnUnsuitable())
    {
        LOGD("Dropping block at {%d, %d, %d} because it is in an unsuitable place", a_BlockX, a_BlockY, a_BlockZ);
I get the following output:
Code:
[b2179b70|14:25:53] CanBe: 255
[b2179b70|14:25:53] Dropping block at {-9, 66, 7} because it is in an unsuitable place

WTF? if CanBe is 255, then how come the code's taking the if() path???


RE: Weird gcc behavior - ThuGie - 11-19-2012

just for fun have you tried if(CanBe == 0) { just for the fun of it just random differences might fix it.
Why its doing this no clue.
As canbe is set normaly i doubt its overwriten .. before its checked.


RE: Weird gcc behavior - FakeTruth - 11-19-2012

Also, just to be clear, shouldn't CanBe log as 1 in the console instead of 255 normally?


RE: Weird gcc behavior - xoft - 11-19-2012

It needn't. It's a bool value and any nonzero is "true". That's why I made a commit recently removing all "== true" comparisons - they needn't work as intended, two true values needn't be equal Wink
When I get home (yes, I'm on a train), I'll try putting the CanBe into the log inside the condition, to see if it changed externally; but that is highly unlikely.


RE: Weird gcc behavior - xoft - 11-19-2012

Hmm, so it seems the standard says that any number can be converted to a boolean according to the rule "zero is false, nonzero is true), but bool veriables only hold the value of zero or one. However, we do a memset(BoolArray, 0xff, ...); which breaks this.

I actually verified this by looking at the disassembly produced by gcc - it checks specifically for the value "1", in the "if (!CanBe)"


RE: Weird gcc behavior - FakeTruth - 11-19-2012

Ah, interesting. So do a memset(BoolArray, 1, ...); right? Or even change 1 to true

I see you changed it to loop through all indices and set it to true. But memset should work too right? Because it sets memory per byte, and a boolean is a byte in memory


RE: Weird gcc behavior - xoft - 11-19-2012

I think I've read somewhere that the compiler can decide to have bool whatever size it wants, it's not specified in the standard. And if it indeed used ints, memset won't work.
Optimalizator should be smart enough, anyway, to transform the for loop into something more efficient - usually a memset or equivalent.


RE: Weird gcc behavior - FakeTruth - 11-19-2012

Yeah I suppose you're right. It's great to have a single standard! /sarcasm
Though there's probably a good reason why it is like it is..