Search code examples
c++gccc++03c++98

= NULL, and non-static data member initializing in c++98


before all:
In C++98, C++03 - Non-static data member initialisers (NSDMIs) do not exist.
https://wandbox.org/ - online compiler you can change the gcc version etc.

Okay now let's consider some code (in c++98, or c++03):

#include <iostream>
struct test {
    void *x = NULL;
    void *y = 0;  //with (void*)0 here, we get the same results
};
int main() {
    std::cout<<(int)NULL;
}

Since gcc 4.8.1:

void *x = NULL;

is allowed (unexpected), but

void *y = 0;

is not (as expected). // getting "non-static data member initializers only available with -std=c++11 or -std=gnu++11" warning

The zero question is why 0 != NULL here (i thought that #define NULL 0,
or #define NULL (void *)0 )

Main question is why in newer gcc versions, we can initialize: void *x = NULL; without any warning - whereas this pointer is non static, and by default it is not set to NULL (by default void *x; is uninitialized).
And my additional question is how to force older gcc versions to accept it, or is there any tricks to make non static pointer members by default initialized to NULL.

im using: $ g++ prog.cc -Wall -Wextra -O2 -march=native -std=c++98 -pedantic-errors


Solution

  • The zero question is why 0 != NULL here (i thought that #define NULL 0, or #define NULL (void *)0` )

    GCC suppresses certain warnings about invalid code in system headers, such as using C++11 features in C++98 code. Because NULL is a macro defined in a system header GCC gets confused and thinks the invalid code is in a system header, so it doesn't warn here. When you use 0 it warns, because it isn't confused about the location.

    N.B. (void*)0 is not a valid definition of NULL in C++, because it would mean this doesn't compile:

    int* p = NULL;
    

    In C you can convert void* to int* but not in C++.

    Main question is why in newer gcc versions, we can initialize: void *x = NULL; without any warning - whereas this pointer is non static, and by default it is not set to NULL (by default void *x; is uninitialized).

    It's a bug, GCC should give a diagnostic about this code.

    And my additional question is how to force older gcc versions to accept it,

    GCC 4.7 will accept it with a warning. You can't make older versions accept it (even with -std=c++0x), because support for default member initializers wasn't added until 4.7

    or is there any tricks to make non static pointer members by default initialized to NULL.

    Define a constructor and set the members there.