我有一个文件“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函数,并且此函数的声明在命名空间net内.在优化版本中,例如-O2,将调用宏替换.
您可以使用gcc -O0 -E v / s gcc -O2 -E预编译程序来验证这一点
当使用htons时
在-O2,htons被翻译成
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; } )); }
error: ‘htons’ was not declared in this scope
当使用net :: htons时
使用net :: ntohs替换ntohs时,使用ntohs define进行优化,并将预处理的代码看作:
int main() { net::(__extension__ ({... /* removed for Brevity */ ...})); }
因而错误
error: expected unqualified-id before ‘(’ token
为什么它可以实现为函数或宏.如果它被定义为宏,htons将正常工作.但是如果将它定义为函数net :: htons就可以了.
可能的解决方案
using namespace net; // Not recommended
#ifndef htons // Recommended using net::htnos; #endif
extern "C" { // Add all declarations in global space #include <arpa/inet.h> }