The following code on a RH7.2 machine will compile with gcc 3.2.2, but not 3.3. #include <stdlib.h> inline static double abs(double a) { return a>=0? a : -a; } #include <ext/hash_map> 3.3 complains: /include/c++/3.3/cmath: In function `double std::abs(double)': /include/c++/3.3/cmath:172: error: `double std::abs(double)' conflicts with previous using declaration `double abs(double)' Weeding through the preprocessed output (g++ -E foo.cc | egrep -e "\babs\b"), I see that 322 has the following declarations: extern int abs (int __x) throw () __attribute__ ((__const__)); inline static double abs(double a) { return a>=0? a : -a; } using ::abs; abs(long __i) { return labs(__i); } abs(long long __x) { return __x >= 0 ? __x : -__x; } using __gnu_cxx::abs; The first is from <stdlib.h>, the second is from foo.cc, and the last 4 result from <ext/hash_map> pulling in <cstdlib> Using this to whittle down the test case I get: extern "C" { extern int abs (int __x) throw () __attribute__ ((__const__)); extern long int labs (long int __x) throw () __attribute__ ((__const__)); } inline static double abs(double a) { return a>=0? a : -a; } namespace std { using ::abs; long abs(long __i) { return labs(__i); } } namespace __gnu_cxx { long long abs(long long __x) { return __x >= 0 ? __x : -__x; } } namespace std { using __gnu_cxx::abs; } Which compiles on both 3.2.2 and 3.3... however... Looking at the preprocessed 3.3 out put I see: extern int abs (int __x) throw () __attribute__ ((__const__)); inline static double abs(double a) { return a>=0? a : -a; } using ::abs; abs(long __i) { return labs(__i); } abs(long long __x) { return __x >= 0 ? __x : -__x; } using __gnu_cxx::abs; abs(double __x) abs(float __x) abs(long double __x) The three final lines are new and come from <cmath>. Using this to produce a test case yields: extern "C" { extern int abs (int __x) throw () __attribute__ ((__const__)); extern long int labs (long int __x) throw () __attribute__ ((__const__)); } inline static double abs(double a) { return a>=0? a : -a; } namespace std { using ::abs; long abs(long __i) { return labs(__i); } } namespace __gnu_cxx { long long abs(long long __x) { return __x >= 0 ? __x : -__x; } } namespace std { using __gnu_cxx::abs; } // new part: namespace std { inline double abs(double __x) { return __builtin_fabs(__x); } inline float abs(float __x) { return __builtin_fabs(__x); } inline long double abs(long double __x) { return __builtin_fabs(__x); } } Which neither 3.2.2, nor 3.3 like, both complaining: In function `double foo.cc:std::abs(double)': foo.cc:32: error: `double std::abs(double)' conflicts with previous using declaration `double abs(double)' Another data point: Just replacing <ext/hash_map> with <cmath> does not cause this. Hope this was useful. -Kenny This was with "gcc version 3.3" and "gcc version 3.2.2"
Hello, I can confirm that this problem is present on gcc 3.3 branch and mainline (20030525). Dara
*** Bug 11472 has been marked as a duplicate of this bug. ***
This is a dup of 11409 which is caused by builtins. *** This bug has been marked as a duplicate of 11409 ***
Actually this was not a dup (the one I marked as a dup of this one was really a dup of the other bug) but invalid as the extern "C" stuff is right in C++ and the abs function in the namespace std has to be the same function (point to the same memory) and including one of the standard headers can include others.