Yet another slap on the hand by implicit bool to int conversions

Andrej Mitrovic andrej.mitrovich at gmail.com
Sun Jun 19 13:13:06 PDT 2011


So I've had a pretty fun bug today when porting some code over to D.
When I port C code to D, first I do a one-to-one translation and make
sure everything works before I try to make use of any D features.

Here's a function snippet, try to figure out what's wrong with the
code (don't worry about type definitions or external variables yet):

http://codepad.org/gYNxJ8a5

Ok that's quite a bit of code. Let's cut to the chase:

if (mmioRead(hmmio, cast(LPSTR)&drum, DRUM.sizeof != DRUM.sizeof))
{
    mmioClose(hmmio, 0);
    return szErrorCannotRead;
}

Here goes: The first argument to "mmioRead" is the already opened file
handle, the second is the instance variable to write to (a struct
variable of type DRUM), and the third argument is the number of bytes
to read (an integer).

On success, the function will return the number of bytes read. We
compare this to the size of the DRUM structure, and if the sizes are
not equal then something has gone wrong. I've added a writeln() call
inside the if body to verify that the if statement body is never
executed.

Yet, I have no data in the "drum" variable after the call! What on
earth did go wrong?

Let's take a closer look at the call:

if (mmioRead(hmmio, cast(LPSTR)&drum, DRUM.sizeof != DRUM.sizeof))

Look at that nasty parenthesis at the end, it's not in the right
position at all! It should be:

if (mmioRead(hmmio, cast(LPSTR)&drum, DRUM.sizeof) != DRUM.sizeof)

So, what happened with the original call?

This expression: DRUM.sizeof != DRUM.sizeof
was evaluated and converted to this boolean: false
which was implicitly converted to an int: 0
which means mmioRead has read 0 bytes, and remember how this function
returns the number of bytes it has read? Well it returns 0.
0 in turn is implicitly converted to a bool, and the if body is not executed.

Btw, this is all compiling with all the warnings turned on. If I had
at least a warning emitted from the compiler I could have spotted the
bug sooner and not waste time due to silly (admittedly my) typos like
these.


More information about the Digitalmars-d mailing list