C ++在命名空间前缀parsing和优化级别依赖关系中使用extern“C”

我有一个文件“test.cxx”

namespace net { extern "C" { #include <arpa/inet.h> } } int main() { htons(1024); } 

编译-O1或更多时,一切正常。

-O0编译时:

 error: 'htons' was not declared in this scope suggested alternative: 'net::htons' 

然后我把htons改成net :: htons

编译-O0时一切正常。

编译-O1或更多时:

 error: expected unqualified-id before '(' token 

转载gcc-4.9.2和clang-3.7.0。 有人可以解释为什么会发生?

发生这种情况是因为在-O0 ,调用被编译为htons函数,并且你的声明是在这个函数里面的。 在优化版本中,例如-O2 ,调用被替换为宏。

你可以通过使用gcc -O0 -E v / s gcc -O2 -E预编译你的程序来验证

当使用htons时
-O2htons被翻译成

 int main() { (__extension__ ( { register unsigned short int __v, __x = (unsigned short int) (1024); if (__builtin_constant_p (__x)) __v = ((unsigned short int) ((((__x) >> 8) & 0xff) | (((__x) & 0xff) << 8))); else __asm__ ("rorw $8, %w0" : "=r" (__v) : "0" (__x) : "cc"); __v; } )); } 

使代码不会抛出分辨率错误。

错误:'htons'没有在这个范围内声明

当使用net :: htons时

当你用net::ntohs替换ntohs时, ntohs define被使用/暴露以进行优化,你的预处理代码如下所示:

 int main() { net::(__extension__ ({... /* removed for Brevity */ ...})); } 

因此错误

错误:预期在'('标记之前的非限定id

为什么发生
htons可以作为函数或宏来实现。 如果它被定义为宏, htons会正常工作。 但如果它被定义为一个函数net::htons会正常工作。

它出现在-O1或更高版本,头文件暴露宏版本,而不是功能。

可能的解决方案

 using namespace net; // Not recommended 
 #ifndef htons // Recommended using net::htnos; #endif 
 extern "C" { // Add all declarations in global space #include <arpa/inet.h> }