You are not logged in.
#include <arpa/inet.h>
int main()
{
uint32_t ip;
ip = ::htonl(ip);
return 0;
}
Saved as test.cc...
compiling...
$ g++ -g test.cc
$ g++ -O2 test.cc
test.cc: In function 'int main()':
test.cc:7: error: expected id-expression before '(' token
$ g++ --version
g++ (GCC) 4.3.1 20080724 (prerelease)
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
The same code compiles with success or gives an error changing optimization?
What does it mean?
Last edited by ezzetabi (2008-08-19 14:03:32)
Offline
If you remove the "::", it compiles with -O2. Don't know why!
Offline
Why did you write ::htonl ?
htonl is a simple function...
Shaika-Dzari
http://www.4nakama.net
Offline
Why did you write ::htonl ?
That is just explicitly scoping the function to be from the global namespace. A bit overkill for this simple example but useful in more complicated code.
As far as I can tell, this code should compile and that it doesn't with -O2 is a bug. I am no C++ guru however...
Edit: gcc-3.3 may (NOT) help you figure this out!
test.cc: In function `int main()':
test.cc:6: error: syntax error before `__extension__'
test.cc:6: error: `__x' undeclared (first use this function)
test.cc:6: error: (Each undeclared identifier is reported only once for each
function it appears in.)
test.cc:6: error: `__v' undeclared (first use this function)
test.cc: At global scope:
test.cc:6: error: syntax error before `)' token
Offline
Running "gcc -E test.cc > raw.cc" and "gcc -O2 -E test.cc > opt.cc" and you will note what -O2 is doing to your code.
ip = ::htonl(ip);
is being replaced with
ip = ::(__extension__ ({ register unsigned int __v, __x = (ip); if (__builtin_constant_p (__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) << 8) | (((__x) & 0x000000ff) << 24)); else __asm__ ("rorw $8, %w0;" "rorl $16, %0;" "rorw $8, %w0" : "=r" (__v) : "0" (__x) : "cc"); __v; }));
Note the global namespace operator is still there which is wrong. So I say this is definitely a gcc bug.
Offline
@Kknd
This is the reason of the whole topic... Yes?
@Shaika-Dzari
It is as Allan said. In C++ I always use ::f() for global or legacy C functions. It is about giving an immediate feedback to people who read the code that I am calling a global, not a member function.
Moreover I can make member functions with the same name of global ones without worrying.
Think about a socket class, it can well have a member function called bind(), yet there won't be ambiguity in the code if I always call ::bind() for the global function.
Of course in the example it is an overkill, but when you think you found a bug you have to make a minimal example to show the incorrect behaviour. And here it is.
@Allan
Programming 101: when in doubt use -E and see what the compiler is really seeing.
Yet, I did not thought -E -O2 was meaningful... I thought optimizations were made only after....
So, there is some kind of bug in function inlining. gcc inlines and forgets removing the scope operator.
Thanks a lot Allan.
Last edited by ezzetabi (2008-08-20 07:30:22)
Offline
Thank both of you. I have learning something useful today
Shaika-Dzari
http://www.4nakama.net
Offline
int main()
{
uint32_t ip;
ip = (::htonl(ip));
return 0;
}
Compiled perfectly, then tested w/ gdb for other stuff,
.file "test.cpp"
.text
.globl main
.type main, @function
main:
.LFB2:
leal 4(%esp), %ecx
.LCFI0:
andl $-16, %esp
pushl -4(%ecx)
.LCFI1:
pushl %ebp
.LCFI2:
movl %esp, %ebp
.LCFI3:
pushl %ecx
.LCFI4:
subl $20, %esp
.LCFI5:
movl -8(%ebp), %eax
movl %eax, (%esp)
call htonl
movl %eax, -8(%ebp)
movl $0, %eax
addl $20, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.LFE2:
.size main, .-main
.ident "GCC: (GNU) 4.3.1 20080724 (prerelease)"
.section .note.GNU-stack,"",@progbits
<<disassembly.
No bug AFAIK. The scope operator tries to seek out the root of the obj/function, therefore using parentheses where you might use them gives the desired output in your case. When the parentheses are removed, it also does compile. No bug here.
Last edited by piotroxp (2008-08-30 14:00:56)
I invented EM Field Patterns and fixed Feynmann's Diagrams so they are physical.
Offline
I run into similar problem with Window$ API may times. Lots of "functions" are actually macros, where :: operator will fail.
Offline
The correct code is:
#include <arpa/inet.h>
int main()
{
uint32_t ip = 0x01234567;
ip = htonl(ip);
return 0;
}
Using scope operator before htonl is invalid since it's a macro and macros don't have any scoping.
Offline