__cplusplus revisited

Stephen Webb stephen.webb@cybersafe.com
Sun Apr 1 00:00:00 GMT 2001


On Tue, 13 Feb 2001, Neil Booth wrote:
> stephen.webb@cybersafe.com wrote:-
> 
> > I have several flavours of Solaris.  Could someone give me links to
> > the problem and I'll see what I can do?
> 
> OK, great.  Apply the patch below and bootstrap C and C++.  The
> problems are that defining __cplusplus to 199711L reveals different
> aspects of the Solaris headers owing to conditional compilation, and
> some conflicts occur.  I'm not sure if they occur during compiling
> libstdc++, or after installation when compiling normal user code.

The problem boils down to a possible problem in the Solaris 8 headers.  I'm not sure where to take it from here, so I
would like to defer to the greater wisdom.

The problem can be summarized by the following test program the CPLUSPLUS would be __cplusplus except gcc 2.95.2
would not allow me to redefine that macro from the command line).

// begin code
typedef long test_t;

#if  CPLUSPLUS >= 199711L
namespace std
{
    typedef long test_t;
}

using std::test_t;
#endif


int
main(int argc, char* argv[])
{
    test_t	aValue = CPLUSPLUS;
    return 0;
}
// end code

Under the native Solaris 8 C++ compiler (Sun WorkShop Compilers C++ 6) and under gcc 2.95.2 on any platform I cared
to test on, the above code would compile (with -DCPLUSPLUS=199711L).  Under the latest CVS gcc the compiler would
error with the error "using directive `test_t' introduced ambiguous type `test_t'."

Note that there are no using directives in the code, but there is a using declaration, so the error message is a
little misleading.  A using directive makes the name visible, but allows clashes.

This problem has nothing to do with the libstdc++ headers and can be reproduced with the latest CVS gcc on Solaris 8
when trying to compile this program:

// begin code
#include <unistd.h>
main() {}
// end code

The code produced by the supplied headers clearly produces a name clash at global scope, and I would think it's the
code that is in error (someone please correct me if I'm wrong).  The solution is less simple.

The Solaris header /usr/include/sys/types.h has a typedef for, for example, size_t in the global namespace. 
Wonderful.

Several Solaris ISO headers (/usr/include/iso) also typedef size_t on their own in the std namespace if __cplusplus
>= 199711L.  This is regardless of whether size_t has been defined already in the global namespace (ie. the _SIZE_T
guard macro).  So far, so good.

Several Solaris headers in /usr/include, such as stddef.h, time.h, etc. have using declarations that put the std
typedefs in the global namespace as well.  This is the problem.

What should change to provide the correct solution?  I don't know what's "right" according to the standard, but I can
think of two possible simple solutions.

(1) Use fixincl to eliminate the global typedefs in types.h if __cplusplus is 199711L (perhaps making them live only
in std)

(2) Change all the other headers to pull the global typedefs into std instead of foisting std into the global
namespace.

What do you all think?


Stephen M. Webb



More information about the Libstdc++ mailing list