nullptr_t未在g ++ 4.9.2上定义

时间:2015-01-28 17:58:39

标签: c++ c++11 g++

我正在使用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

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

你是否知道为什么这个nullptr_t检查失败了g ++ 4.9.2以及如何修复它?

修改

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

2 个答案:

答案 0 :(得分:7)

nullptr_t未由预处理器定义,因此让预处理器检查它是行不通的。 nullptrg++-4.9.2定义了-std=c++11 int main() { std::nullptr_t i = nullptr; } ,快速测试程序可以验证。

{{1}}

答案 1 :(得分:7)

我认为你误解了#ifdef测试的内容。具体地

#if defined identifier

将(来自§16.1,强调我的):

  如果标识符当前被定义为宏名称,则

评估为1(即,如果它是预定义的,或者如果它是   已成为#define预处理指令的主题,没有干预#undef指令   相同的主题标识符),如果不是,则为0。

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

  

nullptr_t定义如下:

namespace std {
    typedef decltype(nullptr) nullptr_t;
}

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

int main() {
    #ifdef int
    std::cout << "int is defined" << std::endl;
    #endif
}

您想要的测试是:

#if __cplusplus >= 201103L
    // C++11
#else
    // not C++11
#endif

来自gcc docs

  

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