我有一个文件“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
函数,而您对该函数的声明在namespace 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;
}
));
}
使代码不抛出解析错误。
当使用 net::htons 时
当您用
ntohs
替换 net::ntohs
时,ntohs
定义被使用/公开以进行优化,并且您的预处理代码如下所示:int main() {
net::(__extension__ ({... /* removed for Brevity */ ...}));
}
因此错误
为什么会发生
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>
}
关于命名空间前缀解析和优化级别依赖中带有 extern "C"的 C++,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28872710/