C ++ with extern" C"在名称空间前缀解析和优化级别依赖

时间:2015-03-05 07:57:29

标签: c++ c linux

我有一个带有

的文件“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上。 有人能解释为什么会这样吗?

1 个答案:

答案 0 :(得分:12)

这是因为在-O0,调用被编译为htons函数,并且此函数的声明在namespace net内。例如,在优化版本-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时

当您使用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>
}