我有一个带有
的文件“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上。 有人能解释为什么会这样吗?
答案 0 :(得分:12)
这是因为在-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;
}
));
}
使代码不会抛出分辨率错误。
错误:'htons'未在此范围内声明
使用net :: htons时
当您使用ntohs
替换net::ntohs
时,会使用ntohs
define进行优化,并且您的预处理代码如下所示:
int main() {
net::(__extension__ ({... /* removed for Brevity */ ...}));
}
因而错误
错误:在'('token
之前预期的非限定标识
为什么会发生
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>
}