我正在使用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
答案 0 :(得分:7)
nullptr_t
未由预处理器定义,因此让预处理器检查它是行不通的。 nullptr
中g++-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
的未指定值。