Bug 6257 - [DR 456] C-library symbols enter global namespace
Summary: [DR 456] C-library symbols enter global namespace
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: unknown
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 6664 8295 9975 9977 10425 12629 16668 19279 26153 27255 32371 38531 (view as bug list)
Depends on:
Blocks:
 
Reported: 2002-04-11 09:26 UTC by marc-oliver.gewaltig
Modified: 2019-11-27 08:48 UTC (History)
20 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2006-01-08 05:21:06


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description marc-oliver.gewaltig 2002-04-11 09:26:00 UTC
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;
}
Comment 1 marc-oliver.gewaltig 2002-04-11 09:26:00 UTC
Fix:
Put all C symbols in the namespace std, if included
by <c*> headers.
Comment 2 phil 2002-04-11 15:35:31 UTC
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

Comment 3 marc-oliver.gewaltig 2002-04-12 09:44:33 UTC
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           
 ==========================================================

Comment 4 phil 2002-04-25 16:46:39 UTC
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.
 
Comment 5 Nathan Sidwell 2002-09-15 11:22:59 UTC
State-Changed-From-To: open->analyzed
State-Changed-Why: this is a library issue, and somewhat system dependant.
Comment 6 Anders Wäänänen 2003-05-28 07:00:56 UTC
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
Comment 7 Andrew Pinski 2003-06-01 21:45:59 UTC
*** Bug 9977 has been marked as a duplicate of this bug. ***
Comment 8 Andrew Pinski 2003-06-01 23:10:58 UTC
*** Bug 10425 has been marked as a duplicate of this bug. ***
Comment 9 Andrew Pinski 2003-06-01 23:13:15 UTC
*** Bug 9975 has been marked as a duplicate of this bug. ***
Comment 10 Andrew Pinski 2003-07-06 19:42:26 UTC
*** Bug 8295 has been marked as a duplicate of this bug. ***
Comment 11 Andrew Pinski 2003-10-15 22:49:21 UTC
*** Bug 12629 has been marked as a duplicate of this bug. ***
Comment 12 Paolo Carlini 2003-11-16 20:58:07 UTC
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...
Comment 13 Andrew Pinski 2004-07-22 08:48:29 UTC
*** Bug 16668 has been marked as a duplicate of this bug. ***
Comment 14 Andrew Pinski 2005-01-05 20:24:54 UTC
*** Bug 19279 has been marked as a duplicate of this bug. ***
Comment 15 Nathanael C. Nerode 2005-10-03 03:42:06 UTC
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.
Comment 16 Andrew Pinski 2006-02-07 12:41:11 UTC
*** Bug 26153 has been marked as a duplicate of this bug. ***
Comment 17 Marc Glisse 2006-04-18 15:10:47 UTC
(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).
Comment 18 Paolo Carlini 2006-04-18 17:49:44 UTC
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
Comment 19 Marc Glisse 2006-04-19 11:09:39 UTC
(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...
Comment 20 Paolo Carlini 2006-04-19 11:19:54 UTC
(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.
Comment 21 Marc Glisse 2006-04-19 11:38:22 UTC
(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.
Comment 22 Paolo Carlini 2006-04-19 11:44:03 UTC
(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.
Comment 23 Andrew Pinski 2006-04-22 02:09:30 UTC
*** Bug 27255 has been marked as a duplicate of this bug. ***
Comment 24 Gabriel Dos Reis 2006-04-30 23:05:27 UTC
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
Comment 25 Andrew Pinski 2006-04-30 23:06:53 UTC
Suspending based on the Defect report being still open.
Comment 26 Paolo Carlini 2007-06-16 22:07:26 UTC
*** Bug 32371 has been marked as a duplicate of this bug. ***
Comment 27 Paolo Carlini 2007-06-16 22:19:33 UTC
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.
Comment 28 Paolo Carlini 2008-12-15 18:42:54 UTC
*** Bug 38531 has been marked as a duplicate of this bug. ***
Comment 29 Paolo Carlini 2010-02-05 13:16:21 UTC
Given the resolution of DR 456 [CD1], this is invalid, that is, the snippet can well compile (and does, with libstdc++-v3).
Comment 30 Jackie Rosen 2014-02-16 13:12:32 UTC Comment hidden (spam)
Comment 31 Andrew Pinski 2019-11-27 08:48:03 UTC
*** Bug 92688 has been marked as a duplicate of this bug. ***