C ++ with extern "C" in resolving namespace prefix and depending on optimization level

I have a test.cxx file with

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

When compiling with -O1 or more, everything is fine.

When compiling with -O0 :

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

Then I change htons to net :: htons .

When compiling with -O0, everything is fine.

When compiling with -O1 or more:

 error: expected unqualified-id before '(' token 

This is reproduced on gcc-4.9.2 and clang-3.7.0. Can someone explain why this is happening?

+7
c ++ c linux
source share
1 answer

This is because in -O0 call is compiled into the htons function, and your declaration for this function is inside namespace net . In the optimized version of -O2 , for example, the call is replaced by a macro.

You can verify this by precompiling your program using gcc -O0 -E v / s gcc -O2 -E

When using htons
In -O2 , htons translates to

 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; } )); } 

Generating code will not result in a permission error.

error: 'htons has not been declared in this area

When using net :: htons

When replacing ntohs with net::ntohs , ntohs define is used / displayed for optimization, and your pre-processed code looks like:

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

And therefore a mistake

error: expected unqualified-id before '(token

Why is this happening
htons can be implemented as a function or macro. If it is defined as a macro, htons will work fine. But if it is defined as a net::htons , it will work fine.

It displays in -O1 or higher, header files display macro versions instead of functions.

Possible solutions

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

All Articles