tags:

views:

156

answers:

1

I'm using MSVC and it seems like the code below does not crash and the function pointer is initialized to NULL by the compiler.

int (*operate)(int a, int b);
int add(int a, int b)
{
    return a + b;
}

int subtract(int a, int b)
{
    return a - b;
}

int main()
{


    if(operate) //would crash here if not NULL
    {
        cout << operate(5,5);
    }

    operate = add;
    if(operate)
    {
        cout << operate(5,5);
    }

    operate = subtract;
    if(operate)
    {
        cout << operate(5,5);
    }
    return 0;
}

So it seems MSVC initializes function pointers to NULL, but if I build this on gcc in Linux would it also be NULL? Is it conventional or MSVC specific, can I rely on it being NULL wherever I go?

Thanks

+14  A: 

operate is initialised to NULL because it is a global variable, not because it is a function pointer. All objects with static storage duration (which includes global variables, file-level static variables and static variables in functions) are initialised to 0 or NULL if no initialiser is given.

[EDIT in response to Jim Buck's comment:] In C++, this is guaranteed by clause 3.6.2/1 of the language standard, which begins:

Objects with static storage duration (3.7.1) shall be zero-initialized (8.5) before any other initialization takes place. Zero-initialization and initialization with a constant expression are collectively called static initialization; all other initialization is dynamic initialization.

I expect the same behaviour is true of C, since C++ is designed to be compatible with it on most things, although I don't have the standard for it.

[EDIT #2] As Jeff M points out in a comment, it's important to realise that variables of automatic storage duration (that is, "ordinary" local variables) are not automatically zero-initialised: unless an initialiser is given, or they are assigned values by a constructor, they will initially contain random garbage (whatever was already sitting in memory at that location). So it's a good habit to initialise all variables -- it can't hurt but can help.

j_random_hacker
Global/static variables are not guaranteed to be zero-initialized. They might in a debug build, but even that's not guaranteed.
Jim Buck
@Jim: Indeed they are so guaranteed in C++. I will add a reference to the relevant paragraph from the standard to my post.
j_random_hacker
My comment on the question might be relevant. "You have an uninitialized global and the compiler will usually put that in the [`.bss`](http://en.wikipedia.org/wiki/.bss) segment which is zero-initialized."
Jeff M
@Jeff: whether or not the compiler chooses to put them in the `.bss` segment, they **must** be initially zero. This is required by both the C and C++ language standards.
R..
@R.. I thought it was this way also, this answer seems to suggest that for C it is otherwise...
Matt Joiner
The C99 spec section 6.9.2 covers this -- its the same as C++
Chris Dodd
@Matt: Not sure how you came away with the impression that I was suggesting things are different for C. I was just saying I was not certain it was the same. Dunno how I could have been much clearer about that...?
j_random_hacker
Hmm, then this is new since the PlayStation development days (uh-oh, I'm dating myself).. stuff was sure not zero-initialized in a release build back then. That was fun-for-everyone the night of a gold master.
Jim Buck
@Jim: I can see why that stuck in your memory :) C++ compilers have been notorious for implementing the language spec incorrectly -- my guess is a compiler or linker bug caused you that grief. Don't know if that makes it better or worse... :)
j_random_hacker
Worse, always worse! :) Actually, it was gcc 3.x that was being used at the time for PlayStation development.
Jim Buck
In all fairness, we should describe that as "Sony's compiler based on GCC 3". Can't blame the Gnu people for all the weirdness in that compiler". The Sony of America people I met back in 2003 were very apologetic for that.
MSalters