C++: ::ntohs() fails on higher optimization levels
Asked Answered
P

1

9

I have a .cpp file: htonstest.cpp. I use g++ to compile it:

$ g++ -o test htonstest.cpp

It works, and the program ./test works too.

But, when I use automake to compile it, has a compile error:

 htonstest.cpp: In function ‘int main()’: 
 htonstest.cpp:6: error:expected id-expression before ‘(’ token.

My OS is CentOS, gcc's version is 4.1.2 20080704, autoconf's version is 2.59, automake's version is 1.9.6.

To reproduce:

$ aclocal
$ autoheader
$ autoconf
$ automake -a
$ ./configure
$ make

ntohstest.cpp:

 #include <netinet/in.h>
 #include <iostream>

 int main()
 {
     short a = ::ntohs(3);
     std::cout << a << std::endl;
     std::cin.get();
     return 0;
 }

configure.ac:

 AC_PREREQ(2.59)
 AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
 AC_CONFIG_SRCDIR([htonstest.cpp])
 AC_CONFIG_HEADER([config.h])
 AM_INIT_AUTOMAKE([foreign])
 # Checks for programs.
 AC_PROG_CXX

 # Checks for libraries.

 # Checks for header files.
 # AC_CHECK_HEADERS([netinet/in.h])

 # Checks for typedefs, structures, and compiler characteristics.

 # Checks for library functions.
 AC_CONFIG_FILES(Makefile)
 AC_OUTPUT

Makefile.am:

 bin_PROGRAMS=main
 main_SOURCES=htonstest.cpp
Pleistocene answered 21/1, 2013 at 2:37 Comment(8)
try add using namespace std;Taiwan
@JohnTortugo: Nice guess, but no.Doubletongued
What resource told you to use ::ntohs?Planogamete
en, good question, I don't know too. I think there is only one reason:(old code):-).Pleistocene
@LightnessRacesinOrbit : It'd be some code to be ported from Windows, not simply some "old code". As far as I know, "::ntohs" is correct in Windows.Circle
I just don't see why you'd ever use the leading ::. It just introduces portability issues, like this one. Whoever used it first and told their friends to do the same needs a slap in the face.Planogamete
@LightnessRacesinOrbit: Windows programmers are from Mars, Unix programmers are from Venus (and we have the source code, too)).Doubletongued
@LightnessRacesinOrbit: So that you don't accidentally have the name resolve to something other than what you expect? Especially relevant for stuff like ::send.Creativity
D
14

This is actually unrelated to autotools, and I was quite surprised when I tested your program. The relevant code is in netinet/in.h...

#ifdef __OPTIMIZE__
...
# define ntohs(x) ...
...
#endif

The reason that the code fails under Automake is because Automake defaults to -O2, and when -O2 is enabled, ntohs() is a macro.

The fix

Use ntohs(3) instead of ::ntohs(3).

The alternative fix

Add the following line after your includes:

#undef ntohs

Documentation

The byteorder(3) manpage reads:

The htons() function converts the unsigned short integer hostshort from host byte order to network byte order.

So in my opinion, it is at best rude for the library to define an htons() macro.

Doubletongued answered 21/1, 2013 at 2:45 Comment(2)
Oh, GREAT,THANK YOU, you tell me the reason.thanks very much.Pleistocene
" So in my opinion, it is at best rude for the library to define an htons() macro. " Actually, POSIX says "The following [(htonl, htons, ntohs, nothl)] shall be declared as functions, or defined as macros, or both. If functions are declared, function prototypes shall be provided." pubs.opengroup.org/onlinepubs/9699919799/basedefs/…Singularize

© 2022 - 2024 — McMap. All rights reserved.