= NULL,并且非静态数据成员在c ++ 98中初始化

mar*_*k01 5 c++ gcc c++03 c++98

之前:
在C ++ 98,C ++ 03中-非静态数据成员初始化程序(NSDMI)不存在。
https://wandbox.org/-在线编译器,您可以更改gcc版本等。

好的,现在让我们考虑一些代码(在c ++ 98或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;
}
Run Code Online (Sandbox Code Playgroud)

从gcc 4.8.1开始:

void *x = NULL;

允许(意外),但

void *y = 0;

不是(按预期)。//得到“ non-static data member initializers only available with -std=c++11 or -std=gnu++11”警告

零问题是,为什么0!= NULL这里(我认为#define NULL 0
#define NULL (void *)0

主要问题是为什么在较新的gcc版本中,我们可以初始化: void *x = NULL;没有任何警告-而此指针是非静态的,并且默认情况下不会将其设置为NULL(默认情况下void *x;未初始化)。
我的另一个问题是如何强制旧版gcc接受它,或者是否有任何技巧可以将非静态指针成员默认初始化为NULL。

我正在使用: $ g++ prog.cc -Wall -Wextra -O2 -march=native -std=c++98 -pedantic-errors

Jon*_*ely 2

零问题是为什么这里 0 != NULL (我认为#define NULL 0, or #define NULL (void *)0` )

GCC 会抑制有关系统标头中无效代码的某些警告,例如在 C++98 代码中使用 C++11 功能。因为NULL是在系统头文件中定义的宏,所以 GCC 会感到困惑并认为无效代码在系统头文件中,所以它不会在这里发出警告。当您使用0它时,它会发出警告,因为它不会对位置感到困惑。

NB(void*)0不是NULLC++ 中的有效定义,因为这意味着无法编译:

int* p = NULL;
Run Code Online (Sandbox Code Playgroud)

在 C 中,您可以转换void*int*C++,但不能在 C++ 中。

主要问题是为什么在较新的 gcc 版本中,我们可以初始化:void *x = NULL;没有任何警告 - 而这个指针是非静态的,并且默认情况下它没有设置为NULL(默认情况下void *x;未初始化)。

这是一个错误,GCC 应该对此代码进行诊断。

我的另一个问题是如何强制旧的 gcc 版本接受它,

GCC 4.7 将接受它并带有警告。您无法让旧版本接受它(即使使用-std=c++0x),因为直到 4.7 才添加对默认成员初始值设定项的支持

或者是否有任何技巧可以使非静态指针成员默认初始化为 NULL。

定义一个构造函数并在那里设置成员。