nullptr_t未在g ++ 4.9.2上定义

sle*_*eur 1 c++ g++ c++11

我正在使用C++ Rest SDK在Linux上的一个项目中使用g ++ 4.9.2与-std = c ++ 11标志设置.

Internaly C++ Rest SDK检查nullptr是否存在:

#if defined nullptr_t
#define NEEDS_NULLPTR_DEFINED 0
#else
#define NEEDS_NULLPTR_DEFINED 1
#endif
#if NEEDS_NULLPTR_DEFINED
#define nullptr NULL
#endif
Run Code Online (Sandbox Code Playgroud)

这个检查在我的机器上失败,导致nullptr被定义为NULL,后来打破了编译.我不太确定g ++或C++ Rest SDK是否应该归咎于这个问题.

你有没有想过为什么这个nullptr_t检查失败了g ++ 4.9.2以及如何修复它?

编辑:

我向C++ REST SDK提交了一个问题:https://casablanca.codeplex.com/workitem/340

Sir*_*Guy 7

nullptr_t未由预处理器定义,因此让预处理器检查它将不起作用. nullptr在被定义g++-4.9.2-std=c++11,其快速测试程序可以验证.

    int main() {
      std::nullptr_t i = nullptr;
    }
Run Code Online (Sandbox Code Playgroud)


Bar*_*rry 7

我想你误解了什么#ifdef测试.特别

#if defined identifier
Run Code Online (Sandbox Code Playgroud)

将(从§16.1,强调我的):

如果标识符当前被定义为宏名称(即,如果它是预定义的,或者如果它是#define预处理指令的主题而没有具有#undef相同主题标识符的干预指令),则求值为1,如果不是,则为0.

它只能检查标识符是否定义#define.但这std::nullptr_t不是一个宏名称 - 它是一个typedef.具体而言(§18.2/ 9):

nullptr_t 定义如下:

namespace std {
    typedef decltype(nullptr) nullptr_t;
}
Run Code Online (Sandbox Code Playgroud)

同样,以下程序不会打印任何内容:

int main() {
    #ifdef int
    std::cout << "int is defined" << std::endl;
    #endif
}
Run Code Online (Sandbox Code Playgroud)

您想要的测试是:

#if __cplusplus >= 201103L
    // C++11
#else
    // not C++11
#endif
Run Code Online (Sandbox Code Playgroud)

来自gcc文档:

__cplusplus
在使用C++编译器时定义此宏.您可以使用它__cplusplus来测试标头是由C编译器还是C++编译器编译.此宏类似于__STDC_VERSION__,它扩展为版本号.根据所选择的语言标准,宏的值是199711L1998 C++标准规定的; 201103L,根据2011 C++标准; 一个未指定的值,严格地大于和201103L启用的实验语言.-std=c++1y-std=gnu++1y