Sunday, June 10, 2012

Programming Gotcha - 1

This is something C programmers do and it is simple mistake. However the mistake can cost you days in debugging. Eventually the mistake turns out to be trivial, however the impact will be huge.

Consider an example cited by my friend:


int main()
{
        uint64_t var = 0;
        var |= (1 << 45);
        printf("%lu\n", var);
}


The above one looks pretty simple right. But there is mistake :-). Where?

Output: 0

Oooooooo... The output is not expected. So what is the problem. See line #4. The constant '1' is treated as 32 bit number by compiler :-). There you go! The shift by left 45 times leads to var being assigned '0' (or invalid number if operation is rotation). You got the point. This can lead to waste of time while debugging. Fortunately gcc warns about this.

warning: left shift count >= width of type [enabled by default]

If you have lot of files, you may even ignore these warnings. It is better to convert these warnings to errors as stated in previous blogs. So how do we correct it? Just typecast!! Since I am using 64 bit machine I have done some ugly ifdef. This can be done in proper way (kindly comment on writing good ifdef or checking for CPU arch). So here is complete program.

#include <stdint.h>
#include <stdio.h>

#define ARCH 64

#ifdef ARCH
        #if ARCH == 64
                #define FORMAT "%lu\n"
        #else
                #define FORMAT "%llu\n"
        #endif
#else
        #define ARCH 32
        #define FORMAT "%lu\n"
#endif

int main()
{
        uint64_t var = 0;
        var |= ((uint64_t)1 << 45);
        printf(FORMAT, var);
}


The output: 35184372088832

You got it right now and no gcc warnings too! As always kindly comment if you have suggestions and improvements.

No comments:

Post a Comment