Bug 36231 - ostream includes unistd.h outside namespace std, polluting
Summary: ostream includes unistd.h outside namespace std, polluting
Status: RESOLVED DUPLICATE of bug 49745
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 4.2.1
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-05-13 19:46 UTC by Ivan Godard
Modified: 2011-07-15 12:09 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ivan Godard 2008-05-13 19:46:16 UTC
Include chain is ostream -> ios -> iosfwd -> bits/c++io.h -> bits/gthr.h -> bits/gthr-default.h -> unistd.h. The same chain also includes pthread.h. These are imported at file scope, not in namespace std, which pollutes the application name space.

I tried to report this to libstdc++ project, but their reporting instructions seem to lead here although strictly there's no problem with the compiler itself.
Comment 1 Andrew Pinski 2008-05-13 20:03:26 UTC
Try 4.3.0 which includes fixes like this.
Comment 2 Jonathan Wakely 2010-04-29 23:16:12 UTC
it would be wrong to declare e.g. open(2) and close(2) in namespace std because they are not part of ISO C++, they are part of your OS

If you are referring to ISO C names which get included in the global namespace such as size_t then it is no longer an issue, as per
http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#456
Comment 3 Ivan Godard 2010-04-29 23:35:54 UTC
Reopened, because comment#2 mistakes the problem. I don't want to get anything included into namespace std. However, I also do not want tyo get C header names imported into my application's global space merely because I included a C++ header.

The correct solution to this is for the C++ library to not transitively include any C headers. If the C++ facility requires access to a C library function then the access can be hidden behind an adapter function in the C++ library.

It is commonly assumed that applications will mix-and-match both C and C++ in one program, but some of us are trying to write only in C++ and don't want to be polluted.
Comment 4 Jonathan Wakely 2010-04-30 01:02:36 UTC
hiding them behind an adaptor function has a cost and personally I don't think it's worth fixing which is why I closed it as WONTFIX
I'll leave it open but I'm not interested in fixing it.

It's nothing to do with mixing and matching C and C++, "some of us" write pure C++ (thankyouverymuch) but accept that writing C++ on *nix means platform-specific functions are also available. 

I'm still not sure which names you're talking about, either you mean the names from ISO C (which are explicitly allowed to be declared in the global namespace even when including a C++ library header, so this is WONTFIX) or you mean names from POSIX, which are nothing to do with C and are part of POSIX. If you develop on a POSIX system you should avoid using names reserved by POSIX.
Comment 5 Paolo Carlini 2010-04-30 01:03:51 UTC
Note that Jon closed the PR as WONTFIX not as INVALID. If you are more happy then let's keep it open, but for sure *nothing* will happen for a looonngggg time.
Comment 6 Ivan Godard 2010-04-30 05:28:12 UTC
I guess I'm still not being clear. I'm not using *any* of those names; I'm not using C; I'm not using POSIX. I'm only using ostream, which is a plain old C++ library, but when I include <ostream> I'm getting C library functions like open() - not C++ open, C open() - added to my global space, where they conflict with application identifiers.

Including a C++ include file should not cause any identifiers from the C or POSIX to be gratuitously added to the the user's global space. This is a bug. 

Please check with your colleagues if you still do not understand the problem.

Andrew says 4.3 has fixed this; if so it can be closed FIXED, if verified. But closing it WONTFIX is wrong.
Comment 7 Paolo Carlini 2010-04-30 09:31:51 UTC
To be clear: by definition closing something as WONTFIX is *never* wrong. Closing something as INVALID or FIXED can be wrong. The reason being that it's up to the maintainers to decide that something will not be fixed any time soon and should be simply resolved in the bug database as WONTFIX. Thus it's perfectly ok for the maintainers (like Jon and me) to close this as WONTFIX, even if, in principle, some time in the far future, say breaking the ABI at the same time, one can imagine including fewer C headers as implementation detail. I hope now you understand. That said, if you like seeing your baby around, let's keep in around, but, as I said, don't expect any substantive changes any time soon.
Comment 8 Jonathan Wakely 2010-04-30 09:51:26 UTC
> I guess I'm still not being clear. I'm not using *any* of those names; I'm not

If you're not using the names why do you care?

> using C; I'm not using POSIX. I'm only using ostream, which is a plain old C++
> library, but when I include <ostream> I'm getting C library functions like
> open() - not C++ open, C open() - added to my global space, where they conflict
> with application identifiers.

There is not "C++ open", and you're on a POSIX platform, so there are POSIX interfaces defined, which yes, are defined in terms of C functions.

But how do they conflict with application identifiers if you're not using the names?

> Including a C++ include file should not cause any identifiers from the C or
> POSIX to be gratuitously added to the the user's global space. This is a bug. 
> 
> Please check with your colleagues if you still do not understand the problem.

I understand it, but I'm not going to fix it.

> Andrew says 4.3 has fixed this; if so it can be closed FIXED, if verified. But
> closing it WONTFIX is wrong.

No, he suggested you /try/ 4.3, as it has some reductions in header dependencies, "fixes LIKE this".  

As it's not fixed, FIXED is wrong. I agree the situation isn't ideal, so it's not INVALID, but as I don't plan to do anything about it, WONTFIX seems appropriate. Check with http://gcc.gnu.org/bugzilla/page.cgi?id=fields.html#resolution if you still don't understand the words.

You could consider sending a request to the POSIX C++ working group, requesting that POSIX interfaces do not pollute the global namespace when used by C++ programs. 

Comment 9 Ivan Godard 2010-04-30 14:24:15 UTC
This is not a fault of POSIX, because I'm *not* using POSIX. I'm using C++ ostream. Because I'm not using POSIX I expect to be able to declare (for example) "int open = 0;" without a problem - "open" is not a reserved key word and I'm not #including anything that is *defined* to transitively include a POSIX header. According to my reading of the standard, all standard libraries must export only the names defined by the standard, and any other names they need must be guarded by leading underscores or be within a similarly guarded namespace that has not been opened by "using". My report says that gcc violates that standard, because it gratuitously dumps POSIX names into my global space.

Of course, I may be wrong in my interpretation of the standard - I have been many times before :-)
Comment 10 jsm-csl@polyomino.org.uk 2010-04-30 14:42:11 UTC
Subject: Re:  ostream includes unistd.h outside namespace
 std, polluting

On Fri, 30 Apr 2010, igodard at pacbell dot net wrote:

> namespace that has not been opened by "using". My report says that gcc violates
> that standard, because it gratuitously dumps POSIX names into my global space.

It does more than that - for C++ it defines _GNU_SOURCE and so causes many 
non-standard names to be defined as well.

Fixing this requires cooperation from libc maintainers to provide 
implementation-namespace versions of whatever functions libstdc++ wishes 
to use from its headers that are not included in strict ISO C90+AMD1, and 
I doubt such cooperation will be forthcoming.

Comment 11 Jonathan Wakely 2010-04-30 15:58:26 UTC
(In reply to comment #9)
> My report says that gcc violates
> that standard, because it gratuitously dumps POSIX names into my global space.

And once again, my response said "yes, I know but WONTFIX"
 
> Of course, I may be wrong in my interpretation of the standard - I have been
> many times before :-)

Once again, if you were wrong it would be INVALID.

Noone has said this isn't a bug.
Comment 12 Jonathan Wakely 2011-04-20 15:17:37 UTC
N.B. same issue reported at https://bugzilla.redhat.com/show_bug.cgi?id=502251
Comment 13 Paolo Carlini 2011-04-20 18:42:26 UTC
The last time I checked, the problem boiled down to:

  typedef __gthread_mutex_t __c_lock;

in c_io_stdio.h, which we cannot remove right away for ABI reasons, because we have a __c_lock data member in iostream classes. Of course the member is normally completely unused these days, thus a possible ABI-safe way to attack the problem would be replacing the data member with a dummy member of the same size and alignment, the equivalent of:

  class stream
  {
    union
    {
      char __data[sizeof(__gthread_mutex_t)];
      struct __attribute__((__aligned__ ((__alignof__(__gthread_mutex_t))))) { } __align;
    } __dummy_member;
  };

In order to figure out those quantities, ie, sizeof(__gthread_mutex_t) and __alignof__(__gthread_mutex_t) we could probably use something like [GLIBCXX_COMPUTE_STDIO_INTEGER_CONSTANTS], Ralf, people, what do you think?
Comment 14 Paolo Carlini 2011-04-20 18:44:18 UTC
Ralf, what do you think about my last Comment?
Comment 15 Paolo Carlini 2011-04-20 20:36:30 UTC
Unfortunately the issue seems more complex, because gthr.h is dragged in also via <string>, which is everywhere...
Comment 16 Ivan Godard 2011-04-20 21:06:39 UTC
Would it be possible to wrap each #include of a C file in a namespace, adjusting the references from the C++ library accordingly? The namespace to be used could be shared by all such #includes. Of course, there would have to be some cleverness to finesse the guard macros on the .h files so the user could have both the namespaced indirect inclusion and also an explicit direct inclusion if desired. As far as I've checked, the inclusions appear to be for typedefs and sizes and not for actual functions or data, for which the double inclusion approach might cause trouble.
Comment 17 Ralf Wildenhues 2011-04-20 23:10:26 UTC
(In reply to comment #13)
> The last time I checked, the problem boiled down to:
> 
>   typedef __gthread_mutex_t __c_lock;
> 
> in c_io_stdio.h, which we cannot remove right away for ABI reasons, because we
> have a __c_lock data member in iostream classes. Of course the member is
> normally completely unused these days, thus a possible ABI-safe way to attack
> the problem would be replacing the data member with a dummy member of the same
> size and alignment, the equivalent of:
[...]

> In order to figure out those quantities, ie, sizeof(__gthread_mutex_t) and
> __alignof__(__gthread_mutex_t) we could probably use something like
> [GLIBCXX_COMPUTE_STDIO_INTEGER_CONSTANTS], Ralf, people, what do you think?

It is possible to compute size and alignment of types using Autoconf tests (even when cross-compiling), yes, with AC_CHECK_SIZEOF and AC_CHECK_ALIGNOF.  But you are in a much better position to decide whether that is really sufficient here to solve all pending issues why the headers are dragged in.  Thanks.
Comment 18 Paolo Carlini 2011-04-21 00:02:02 UTC
Thanks Ralf, I didn't know AC_CHECK_SIZEOF and AC_CHECK_ALIGNOF even existed, in similar situations probably I would have dumbly re-invented both basing on AC_COMPUTE_INT ;)

Otherwise, about the issue which prompted my question, seems still tough, because actually gthr.h is included by a few different headers, also in locale, not just via the path explained in the PR. Frankly, I don't know how much we can get into this within the existing ABI... To Ivan I have to remember that we don't control in general the underlying .h headers, it's the usual question, how far we can go without assuming much about the C headers and of course without changing the headers themselves...
Comment 19 Ivan Godard 2011-04-21 00:22:08 UTC
I notice that Bugzilla is carrying this as "enhancement" and "unconfirmed". 

Seems odd :-)
Comment 20 Paolo Carlini 2011-07-15 12:09:04 UTC
49745 has a specific testcase

*** This bug has been marked as a duplicate of bug 49745 ***