"If" conditional does not work properly

While debugging, I noticed that an “if” conditional displayed some pretty strange behavior.

I had code similar to this:

if (SomeFunctionReturningBoolean() == true)
{
// do something…
print “1”;
}
else
{
// do something else.
print “2”;
}

Strangely, even though SomeFunctionReturningBoolean() returned true (as the debugger helpfully noted) – the “else” clause was executed, rather than the “if” clause.

I started investigating this.

First, I suspected a mismatch between the code and the executable. I rebuilt from scratch, but no dice. I manually cleaned all of the intermediate files, nope – same strange behavior.

I then changed the code to the following:

bool fResult = SomeFunctionReturningBoolean();

if (fResult == true)
{
// do something…
print “1”;
}
else
{
// do something else.
print “2”;
}

fResult clearly held “true”, but “2” was still printed.

Next, I changed the code to:

bool fResult = SomeFunctionReturningBoolean();

if (fResult == true)
{
// do something…
print “1”;
}

if (fResult == false)
{
// do something else.
print “2”;
}

Neither “1” nor “2” were printed. Strangely, this seemed to work:

bool fResult = SomeFunctionReturningBoolean();

if (fResult)
{
// do something…
print “1”;
}
else
{
// do something else.
print “2”;
}

it printed “1”. I started wondering whether the function was indeed returning true. I changed to disassembly mode, and to my surprise – I noticed that the function was returning 0x6E, and that the equality check was:

cmp eax, 1

Going deeper into the code, I discovered that a function used by SomeFunctionReturningBoolean() as a basis for its return coded simply did not return any value. The programmer was annoyed by some of the warnings returned by an external include file, and disabled all of the warnings using a pragma – so the “Not all code paths return a value” warning simply did not appear when I compiled the code.

The Visual Studio 2008 debugger treats a bool variable with a value of 0 as false, and it displays “false” as its value in any variable windows. If the bool variable contains anything but 0 – the value displayed is “true”. This is generally correct, since non-zero values are handled as “true” by most conditional assembly instructions. However, a comparison instruction like

if (variable == true)

is compiled to

cmp eax, 1

which does not check for “true”-ness, but rather for equality with 1 – which is the value that “true” signifies in the current Microsoft C++ world.

So – the actual source code compared the bool to a specific value – 1, and since 0x6E is not equal to 1 – the check failed and we executed the “else” clause.

So, what did we learn from this issue?

  1. Never disable all of the warnings using a pragma – disable specific warnings, otherwise you’ll lose important warnings that might appear.
  2. The VS2008 debugger displays “true”/”false” values in the variables window based on a check of “true”-ness, not an equality to the “true” value.
  3. The “Go to assembly” can be very, very useful at times. You should familiarize yourself with it.

Goal of this blog

[2013-03-07, Note: This was the first blog post of “A Programmer’s Blogspot” (now defunct), my programming blog. I decided to just merge everything together and make an incoherent generalized blog about me, my interests and my life. So there you go.]

The goal of this blog is to assist others in solving their own development problems encountered in their work as programmers.

The internet (as indexed by Google) has been an amazing aid to me, offering me solutions to many of the problems I’ve encountered which baffled me. Sometimes, however, I’ve had to read multiple sources to discover the real solution that works for me.

This blog is where I’ll post the results of my research into the various new problems I’ll encounter. I am hoping that Google will index it, and that programmers in need will find it useful.

Good luck :) 

Memcached patch: Item expiration signal to client and extension

I work as a developer in Metacafe. We use memcached as our caching system, and have been using it for a few years now with great results. A while ago, we thought of a neat little concept that made working with memcached much more convenient for us. We patched the memcached code in-house, and have been using this patched code for a while now. We are now offering the concept (and the source code) to the project.

The idea is as follows: currently, whenever an item which has expired is requested from a memcached server, the server immediately unlinks (deletes) the item internally and returns an empty (or null) item to the client. We propose, instead, returning an empty item to the client and extending the expiration time of the item by X seconds (we use 60 seconds), thus returning the expired item to all clients who ask for it in the next X seconds. This behavior repeats itself, after X seconds, and so forth. This behavior should be controlled by a command-line argument, and is off by default.

The benefit is that the client which receives the empty item can refresh the item however it deems fit. There is no race situation and no database “stampede”. The client can access a database and create a new item, storing it to server, knowing it is not racing another client. (Of course, if the server has just been launched or if the item is brand new – there might be a race, but this idea is not an attempt to fix this different issue.)

More information and the patch can be found here