__cplusplus change and headers incompatibility with clang
Clang++ fails to compile some programs (including clang itself) using g++ 4.7 c++ headers. The bug is caused by more strict rules then in g++.
Example error message is the following.
In file included from test1.cpp:2: In file included from /usr/gcc/4.7/include/c++/4.7.3/cstdlib:66: /usr/include/stdlib.h:52:12: error: target of using declaration conflicts with declaration already in scope using std::atof; ^ /usr/include/iso/stdlib_iso.h:124:15: note: target of using declaration extern double atof(const char *); ^ /usr/include/floatingpoint.h:204:15: note: conflicting declaration extern double atof __P((const char *)); ^ In file included from test1.cpp:2: In file included from /usr/gcc/4.7/include/c++/4.7.3/cstdlib:66: /usr/include/stdlib.h:71:12: error: target of using declaration conflicts with declaration already in scope using std::strtod; ^ /usr/include/iso/stdlib_iso.h:157:15: note: target of using declaration extern double strtod(const char *_RESTRICT_KYWD, char **_RESTRICT_KYWD); ^ /usr/include/floatingpoint.h:205:15: note: conflicting declaration extern double strtod __P((const char *, char **)); ^ In file included from test1.cpp:2: /usr/gcc/4.7/include/c++/4.7.3/cstdlib:108:11: error: target of using declaration conflicts with declaration already in scope using ::atof; ^ /usr/include/floatingpoint.h:204:15: note: target of using declaration extern double atof __P((const char *)); ^ /usr/include/iso/stdlib_iso.h:124:15: note: conflicting declaration extern double atof(const char *); ^ In file included from test1.cpp:2: /usr/gcc/4.7/include/c++/4.7.3/cstdlib:129:11: error: target of using declaration conflicts with declaration already in scope using ::strtod; ^ /usr/include/floatingpoint.h:205:15: note: target of using declaration extern double strtod __P((const char *, char **)); ^ /usr/include/iso/stdlib_iso.h:157:15: note: conflicting declaration extern double strtod(const char *_RESTRICT_KYWD, char **_RESTRICT_KYWD); ^
It is cased by atof,strtod and some other functions having the same declarations in std:: and global namespace.
So far, I've found that the following symbols in system headers are affected:
malloc.h: malloc, free, realloc, calloc
floatingpoint.h: atof, strtod
sys/lc_core.h: struct tm;
The first three can be hitted by compiling clang with clang. The last one can be cause by any C++ program including sys/localedef.h .
The problem is that floatingpoint.h and lc_core.h are not in the gate, but comes from separate "closed bins". So I attach two patches: for the gate and for closed bins (we can apply it in distributions).
With these two patches applied clang (with some minor patches) can be built with clang and its test results are the same as for gcc build.
Updated by Alexander Pyhalov almost 9 years ago
I'm not sure about "no one using" - at least during clang compilation it was used in some way. I can see it is used unconditionnaly in lib/ExecutionEngine/IntelJITEvents/jitprofiling.c and in tools/clang/test/SemaCXX/builtin-exception-spec.cpp test. However, in some other cases its use is conditional and depends on HAVE_MALLOC_H.
Updated by Alexander Pyhalov almost 9 years ago
Linux (glibc) still provides malloc.h. FreeBSD malloc.h errors out if STDC is defined. LLVM errors out if malloc.h is removed:
lib/Support/Unix/Process.inc:113:19: error: variable has incomplete type 'struct mallinfo'. Or do you propose to move it in stdlib.h or other header?
Updated by Albert Lee almost 9 years ago
malloc, free, realloc, and calloc were declared by <malloc.h> in POSIX-1988 and the related XPG3 standard. We have K&R C style declarations as well, but the oldest standard we nominally support is XPG3. These predate ANSI and ISO C, which declare them in <stdlib.h>. Later X/Open and POSIX standards follow the C standard in this regard, and the <malloc.h> header is deprecated. However, it is also used for the system-specific mallopt and mallinfo functions.
- Programs written for POSIX-1988, XPG3, or pre-ANSI C that consume malloc/free.
- Programs consuming mallopt or mallinfo.
- Programs written incorrectly that consume malloc/free.
The first case is detectable. The second case and third case are difficult to differentiate, unfortunately. GCC does us the disfavour of defining _POSIX_C_SOURCE by default so we cannot tell when POSIX support is explicitly requested.
We should endeavour to eliminate namespace pollution by hiding these declarations to support current POSIX standards. Unfortunately this will certainly break the third class of programs that still use them, and increase the amount of porting effort. It is probably outside the scope of this change. In order to not break these incorrectly written programs, the current guard around the malloc/free declarations retains them when visibility of XPG3 symbols is requested, which is currently true for newer POSIX versions as well. Thus, it is effectively a no-op until we drop XPG3 support.
rename was formerly an extension to C in POSIX-1988 and XPG3 declared by <unistd.h>, and is declared by <stdio.h> in ANSI and ISO C and the subsequent X/Open and POSIX standards that use standard C. The <unistd.h> header is retained in current POSIX standards, but the declaration of rename has moved to <stdio.h>.
Previously existing guards require \\\\__EXTENSIONS__ to be defined or XPG3 support requested to make this declaration visible. However, requesting XPG4 (in our case, any standard based on XPG4 or later will have this effect) hides the declaration, thus eliminating namespace pollution.
We leave this behaviour unchanged.
Updated by Saulius Krasuckas 4 months ago
I came here from this OI-userland commit:
What's the status?