The C++ standard states that - all C++ header files define their symbols in namespace std - all C header files, used in the form <c*> define their symbol in namespace std (Annex D 5.2,3). However, g++ puts C symbols in the global namespace, even if included via <c**> headers. Release: unknown Environment: Linux (Suse 6.2), Solaris 8, probably all How-To-Repeat: The following version of hello-world should NOT compile with an ISO-14882 compliant compiler #include <cstdio> int main() { // should not work, because printf is in std:: printf("Hello world.\n"); return 0; }
Fix: Put all C symbols in the namespace std, if included by <c*> headers.
From: Phil Edwards <phil@jaj.com> To: marc-oliver.gewaltig@hre-ftr.f.rd.honda.co.jp Cc: gcc-gnats@gcc.gnu.org Subject: Re: c++/6257: C-library symbols enter global namespace Date: Thu, 11 Apr 2002 15:35:31 -0400 On Thu, Apr 11, 2002 at 04:16:58PM -0000, marc-oliver.gewaltig@hre-ftr.f.rd.honda.co.jp wrote: > >Originator: marc-oliver.gewaltig@hre-ftr.f.rd.honda.co.jp > >Release: unknown-1.0 You need to give an actual version number here... the situation is better with GCC 3.x but is still problematic. If you are using 2.x then the library is very outdated. > However, g++ puts C symbols in the global namespace, > even if included via <c**> headers. Yes, we know. The problem is almost impossible to solve without control over the C library. Since we don't provide a C library -- your system vendor gives you that -- we cannot control its contents. Various ideas have been proposed, but nobody has had time to implement them. > >Fix: > Put all C symbols in the namespace std, if included > by <c*> headers. You do realize that this answer was completely useless? "Fix the problem" is an obvious and unhelpful response to "How to fix?" Now, if you have a /patch/, then that would be very helpful. :-) Phil -- If ye love wealth greater than liberty, the tranquility of servitude greater than the animating contest for freedom, go home and leave us in peace. We seek not your counsel, nor your arms. Crouch down and lick the hand that feeds you; and may posterity forget that ye were our countrymen. - Samuel Adams
From: Marc-Oliver Gewaltig <marc-oliver.gewaltig@hre-ftr.f.rd.honda.co.jp> To: Phil Edwards <phil@jaj.com>, gcc-gnats@gcc.gnu.org Cc: Subject: Re: c++/6257: C-library symbols enter global namespace Date: Fri, 12 Apr 2002 09:44:33 +0200 Phil Edwards wrote: > You need to give an actual version number here... the situation is better > with GCC 3.x but is still problematic. If you are using 2.x then the library > is very outdated. Sorry, I think I put this somewhere. I had this problem on g++ 3.0.{2,3,4} > However, g++ puts C symbols in the global namespace, > > even if included via <c**> headers. > > Yes, we know. The problem is almost impossible to solve without control > over the C library. Since we don't provide a C library -- your system > vendor gives you that -- we cannot control its contents. Actually, this issue was a problem for me on Linux, where string.h defines a number of functions which are not part of standard C. In particular char* index() gives me a headache, since it collides with a typedef in my code. My original problem was, that on Linux (with g++ 3.0.{2,3,4}, the following does NOT compile, though it should. And on Linux, there is at least some control over the C library, since it comes from GNU. #include <iostream> namespace test { typedef unsigned int index; } using test::index; int main() { index i=5; return 0; } Isn't it at least possible to threat code correctly which does not explicitly include C headers? > > Various ideas have been proposed, but nobody has had time to implement them. I had the naive idea that if 1. all c++ headers included only <c*> headers and 2. all <c*> headers wrap the <*.h> includes in namespace std the problem should be solved, but maybe I am missing something... > > >Fix: > > Put all C symbols in the namespace std, if included > > by <c*> headers. > > You do realize that this answer was completely useless? "Fix the problem" > is an obvious and unhelpful response to "How to fix?" Sorry, it was meant constructive (see above). As I said, I am probably not deep enough in the matters. > > Now, if you have a /patch/, then that would be very helpful. :-) > Sorry again, but I will have a look... ;-) Oliver -- Dr. Marc-Oliver Gewaltig Future Technology Research ========================================================== Honda R&D Europe (Deutschland) GmbH Carl-Legien-Str. 30 D-63073 Offenbach/Main, Germany Telephone: +49 (0)69-89011-0 ext. -739 Telefax: +49 (0)69-89011-749 E-mail: marc-oliver.gewaltig@hre-ftr.f.rd.honda.co.jp marc-oliver_gewaltig@de.hrdeu.com ==========================================================
From: Phil Edwards <phil@jaj.com> To: marc-oliver.gewaltig@hre-ftr.f.rd.honda.co.jp Cc: gcc-gnats@gcc.gnu.org Subject: Re: c++/6257: C-library symbols enter global namespace Date: Thu, 25 Apr 2002 16:46:39 -0400 On Thu, Apr 11, 2002 at 04:16:58PM -0000, marc-oliver.gewaltig@hre-ftr.f.rd.honda.co.jp wrote: > >Category: c++ This should be libstdc++, but GNATs won't let me fix that. Hmmm. > >Release: unknown-1.0 This makes a difference. Lots of stuff changed between 2.x and 3.x. > >Description: > The C++ standard states that > - all C++ header files define their symbols in namespace std > - all C header files, used in the form <c*> define their symbol in > namespace std (Annex D 5.2,3). > > However, g++ puts C symbols in the global namespace, > even if included via <c**> headers. We know. Interoperating with an arbitrary C library (which is what we are required to do) is quite difficult. As yet very few people have volunteered to work on a solution, and those that have volunteered have very little time. Some of the partial solutions are in the source tree and can be turned on with the appropriate --enable options. To use your two examples, making this work on Linux should be much easier than on Solaris. > >Fix: > Put all C symbols in the namespace std, if included > by <c*> headers. You realize, of course, that this is completely useless? "Fix the problem" is an implied answer. If you'd like to help us work on an actual patch, we'd be very grateful.
State-Changed-From-To: open->analyzed State-Changed-Why: this is a library issue, and somewhat system dependant.
Hi It seems that recent versions of glibc is (almost) prepared to handle the problem raised in this bug report. Using -D_GLIBCPP_USE_NAMESPACES it works - almost. One problem still exist but seem to be solved by: --- /usr/include/wchar.h 2003-04-07 20:56:12.000000000 +0200 +++ wchar.h 2003-05-27 16:00:08.000000000 +0200 @@ -58,10 +58,6 @@ member of the extended character set. */ # define _WINT_T typedef unsigned int wint_t; -#else -# ifdef __USE_GNU -__USING_NAMESPACE_STD(wint_t) -# endif #endif The above patch removes the assuption that wint_t is declared somewhere as part of the std namespace. This seems quite reasonable since you normally get wint_t from stddef.h from your compiler. Anyway it is up to the glibc people to fix. If you then protect the portions in cstdio which pulls the functions into std with an #ifdef _GLIBCPP_USE_NAMESPACES (the functions are already in std courtesy of glibc's use of _GLIBCPP_USE_NAMESPACES) the example works as expected. It is probably not only cstdio that needs tweaking though. My systems are RedHat 8.0: gcc-3.2-7 glibc-2.3.2-4.80.6 and RedHat 9: gcc-3.2.2-5 glibc-2.3.2-27.9 Earlier versions (on eg. RedHat 7.3): gcc-2.96-113 glibc-2.2.5-43 of glibc are not ready to handle _GLIBCPP_USE_NAMESPACES. Cheers Anders -- Anders Wäänänen Phone: +45 353 25301 Niels Bohr Institute Fax: +45 353 25016 Blegdamsvej 17 Email: waananen@nbi.dk DK-2100 Copenhagen Ø Denmark
*** Bug 9977 has been marked as a duplicate of this bug. ***
*** Bug 10425 has been marked as a duplicate of this bug. ***
*** Bug 9975 has been marked as a duplicate of this bug. ***
*** Bug 8295 has been marked as a duplicate of this bug. ***
*** Bug 12629 has been marked as a duplicate of this bug. ***
Unfortunately, the _GLIBCPP_USE_NAMESPACES approach has its own problems: #include <stdio.h> int main() { printf("Hello world.\n"); return 0; } doesn't compile anymore...
*** Bug 16668 has been marked as a duplicate of this bug. ***
*** Bug 19279 has been marked as a duplicate of this bug. ***
So there's a problem with the multiple-include-protection in glibc! We actually want to include the headers twice, potentially -- once when included via <cstdio> et al, with everything in namespaces, and once when included directly via <stdio.h> et al, with everything outside them. They actually shouldn't conflict because that's the whole *point* of putting stuff in a namespace. But we can't do this in any manner because they have multiple-include protection which can't tell the difference. I think this should be solved in glibc. Feel free to forward this suggestion and this code (which I donate to the public domain) to somewhere appropriate. At the beginning of stdio.h, instead of: #ifndef _STDIO_H #define _STDIO_H we would have: #if ( ( defined __cplusplus && defined _GLIBCPP_USE_NAMESPACES ) \ && ! defined _STDIO_H_WITH_NAMESPACES ) \ || ( (! defined __cplusplus || ! defined _GLIBCPP_USE_NAMESPACES )\ && ! defined _STDIO_H ) #if defined __cplusplus && defined _GLIBCPP_USE_NAMESPACES # define _STDIO_H_WITH_NAMESPACES #else # define _STDIO_H #endif For glibc, _GLIPCPP_USE_NAMESPACES could be defined in <cstdio> before the inclusion of stdio.h and undefined afterwards.
*** Bug 26153 has been marked as a duplicate of this bug. ***
(In reply to comment #15) > So there's a problem with the multiple-include-protection in glibc! Yes, the way it is done in solaris is way more convenient. There, stdlib.h includes a file iso/stdlib_iso.h that has all the meat, and then stdlib.h does all the using std::foo; stuff, so cstdlib can just include iso/stdlib_iso.h directly. On solaris, I get quite satisfactory results with: g++ -I/opt/SUNWspro/prod/include/CC/std -D__cplusplus=199711L -U__EXTENSIONS__ -D__STDC__=0 (the include directory contains the cstd headers from sunpro, but they are just one or 2 #include lines) > But we can't do this in any manner because they have multiple-include > protection which can't tell the difference. gcc could come with its own stdlib.h. Both this stdlib.h and cstdlib would include /usr/include/stdlib.h (always with _GLIBCPP_USE_NAMESPACES) and the gcc provided stdlib.h would additionally contain the appropriate using std::foo; lines. The 2 problems I see with this approach are: 1) it means having 2 files with the same name in the search path, and inclusion of the glibc file has to be done with an explicit path of /usr/include (or some other compile time constant) 2) This will do what we want for standard functions, but what about extensions that are declared in stdlib.h in glibc (protected by __USE_ISOC99 or __USE_GNU for example), what happens to them? It might work well, I have not tested. > At the beginning of stdio.h, instead of: > #ifndef _STDIO_H > #define _STDIO_H > we would have: > #if ( ( defined __cplusplus && defined _GLIBCPP_USE_NAMESPACES ) \ > && ! defined _STDIO_H_WITH_NAMESPACES ) \ > || ( (! defined __cplusplus || ! defined _GLIBCPP_USE_NAMESPACES )\ > && ! defined _STDIO_H ) > #if defined __cplusplus && defined _GLIBCPP_USE_NAMESPACES > # define _STDIO_H_WITH_NAMESPACES > #else > # define _STDIO_H > #endif This way you get 2 declarations instead of one and a using directive, I am not sure it won't cause problems (but I don't know).
Probably this PR should be suspended, while waiting for the resolution of DR 456: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#456
(In reply to comment #18) > Probably this PR should be suspended, while waiting for the resolution of DR > 456: > > http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#456 Whether the situation remains the same or the g++ implementation becomes legal does not change the fact that it would be nice (and not at all out of reach) to use the features of glibc and solaris (any others?) that allow a cleaner global namespace when including a <cxxx> header, it would just lower the priority of this from bug to wishitem. And for platforms where it is not possible, then the current implementation will have to remain, whatever the committee decides. But if you want to suspend it, it is your call...
(In reply to comment #19) > (In reply to comment #18) > > Probably this PR should be suspended, while waiting for the resolution of DR > > 456: > > > > http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#456 > > Whether the situation remains the same or the g++ implementation becomes legal > does not change the fact that... I disagree, for many reasons. The issue is more complex, really. For instance - assuming of course the current implementation becomes completely legal - then changing the behavior for some targets and not for others, implies that the very same source code would not be be portable across those targets. I don't think we would like that. Besides, more generally, I'm not at all sure that all the users would actually *like* the new behavior. Indeed, to my best knowldege some implementations which, in principle, could rather easily implement the current standard mandated behavior (for many reasons, for instance are targeting only a small set of systems) decided to *not* implement it by default, on purpose.
(In reply to comment #20) > the > very same source code would not be be portable across those targets. I don't > think we would like that. Besides, more generally, I'm not at all sure that > all the users would actually *like* the new behavior. I meant proposing it as a choice, with a flag like -fclean-global-namespace (better than a macro since it probably means changing the include path and redefining a few macros), which needs not be the default. The current implementation would have to be kept for some platforms anyway, so it could be kept for all.
(In reply to comment #21) > I meant proposing it as a choice, with a flag like -fclean-global-namespace > (better than a macro since it probably means changing the include path and > redefining a few macros), which needs not be the default. The current > implementation would have to be kept for some platforms anyway, so it could be > kept for all. Ok, this makes sense, assuming of course it can be done in a reasonably clean way. I encourage you to try preparing something self-contained (not necessarily complete, not necessarily touching all the headers, at this stage) and post it for further discussion on the libstdc++ list. Thanks.
*** Bug 27255 has been marked as a duplicate of this bug. ***
Subject: Re: C-library symbols enter global namespace "marc dot glisse at normalesup dot org" <gcc-bugzilla@gcc.gnu.org> writes: | (In reply to comment #20) | > the | > very same source code would not be be portable across those targets. I don't | > think we would like that. Besides, more generally, I'm not at all sure that | > all the users would actually *like* the new behavior. | | I meant proposing it as a choice, with a flag like -fclean-global-namespace That is a non-starter. PR better suspended. -- Gaby
Suspending based on the Defect report being still open.
*** Bug 32371 has been marked as a duplicate of this bug. ***
I think the resolution of DR 456 (now [WP]): http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#456 means our behavior is now conforming to the amended Standard.
*** Bug 38531 has been marked as a duplicate of this bug. ***
Given the resolution of DR 456 [CD1], this is invalid, that is, the snippet can well compile (and does, with libstdc++-v3).
*** Bug 260998 has been marked as a duplicate of this bug. *** Seen from the domain http://volichat.com Page where seen: http://volichat.com/adult-chat-rooms Marked for reference. Resolved as fixed @bugzilla.
*** Bug 92688 has been marked as a duplicate of this bug. ***