Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Dear Standard Library, Leave the global namespace alone.

60 views
Skip to first unread message

Frederick Virchanza Gotham

unread,
Jun 27, 2022, 10:37:56 AM6/27/22
to
If I try to compile the following with the GNU compiler (g++):

#include <cstddef>

class size_t {

};

int main(void)
{

}

Then here's what I get back:

size_t.cpp:3:7: error: using typedef-name ‘size_t’ after ‘class’
3 | class size_t {
| ^~~~~~
In file included from /usr/include/c++/11/cstddef:50,
from size_t.cpp:1:
/usr/lib/gcc/x86_64-linux-gnu/11/include/stddef.h:209:23: note: ‘size_t’ has a previous declaration here
209 | typedef __SIZE_TYPE__ size_t;


So basically the compiler is treating <cstddef> as though I'd written <stddef.h>.

Today I tested this small program on 5 compilers:

(1) g++ (Ubuntu 11.2.0-7ubuntu2) 11.2.09
(2) clang version 14.0.0 Target: x86_64-unknown-linux-gnu
(3) Intel Classic C++ Compiler icpc (ICC) 2021.6.0 20220226
(4) Microsoft (R) C/C++ Optimizing Compiler Version 19.32.31329 for x64
(5) Embarcadero C++ 7.60 for Win64

So do I now need to file a bug report with all 5 of these compiler vendors?

Gawr Gura

unread,
Jun 27, 2022, 11:39:04 AM6/27/22
to
On this the C++ standard says

...the contents of each header cname is the
same as that of the corresponding header name.h as specified in
the C standard library (Clause 2). In the C++ standard library,
however, the declarations (except for names which are defined as
macros in C) are within namespace scope (6.4.5) of the namespace
std. It is unspecified whether these names (including any
overloads added in Clause 17 through Clause 33 and Annex D) are
first declared within the global namespace scope and are then
injected into namespace std by explicit using-declarations
(9.9).

You can find this in section 16.4.2.3

Given that the language of the standard says that it is unspecified
whether values from the c prefixed headers (like cstddef) are declared
in the global scope I would say this is not a bug. I think,
unsurprisingly, 5 compilers don't all have it wrong. They are well
within their rights to specify size_t globally before providing
std::size_t. It might be different in previous standard versions of course.

Further, it's my understanding (but I don't have a relevant quotation
for this) that POSIX reserves all identifiers ending in _t for its use.
It wouldn't be surprising, based on that, for Windows to reserve those
names as well. Especially since several C++ keywords (char16_t, wchar_t,
etc.) already make use of the _t suffix.

Bonita Montero

unread,
Jun 27, 2022, 12:06:30 PM6/27/22
to
And how do you feel when you have real problems in life ?

Frederick Virchanza Gotham

unread,
Jun 27, 2022, 12:23:48 PM6/27/22
to
On Monday, June 27, 2022 at 5:06:30 PM UTC+1, Bonita Montero wrote:

> And how do you feel when you have real problems in life ?

I'm currently writing a pre-compiler, and I was getting a mysterious use of "ptrdiff_t" when it wasn't even defined. So I was wondering where it was getting the type definition from.

Scott Lurndal

unread,
Jun 27, 2022, 12:35:52 PM6/27/22
to
Frederick Virchanza Gotham <cauldwel...@gmail.com> writes:
>If I try to compile the following with the GNU compiler (g++):
>
> #include <cstddef>
>
> class size_t {

The suffix _t is reserved to the implementation, IIRC.

Alf P. Steinbach

unread,
Jun 27, 2022, 1:28:08 PM6/27/22
to
The compilers were formally wrong from 1998 till 2010, inclusive.

Then with C++11 the committee (I believe very reluctantly) partially
gave up their absurd stance and let the standard allow the existing
implementations of the language.

To the few C++ programmers who realize this, beginners and professionals
alike, this comes as a shock. The rest, the majority, deny it. It's one
of the large religious (herd belief delusions) issues in C++.


- Alf

Keith Thompson

unread,
Jun 27, 2022, 1:51:39 PM6/27/22
to
By POSIX, not by the language, IIRC.

--
Keith Thompson (The_Other_Keith) Keith.S.T...@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */

Wuns Haerst

unread,
Jun 27, 2022, 1:52:09 PM6/27/22
to
Am 27.06.2022 um 19:51 schrieb Keith Thompson:
> sc...@slp53.sl.home (Scott Lurndal) writes:
>> Frederick Virchanza Gotham <cauldwel...@gmail.com> writes:
>>> If I try to compile the following with the GNU compiler (g++):
>>>
>>> #include <cstddef>
>>>
>>> class size_t {
>>
>> The suffix _t is reserved to the implementation, IIRC.
>
> By POSIX, not by the language, IIRC.
>

Since C++14 !

Keith Thompson

unread,
Jun 27, 2022, 2:55:45 PM6/27/22
to
I just checked the C++17 standard for references to _t being reserved,
and was not successful. Can you provide a citation? (Since there was
no verb in your reply, I'm not entirely sure what you're saying.)

Frederick Virchanza Gotham

unread,
Jun 27, 2022, 6:21:17 PM6/27/22
to
On Monday, June 27, 2022 at 6:28:08 PM UTC+1, Alf wrote:

> The compilers were formally wrong from 1998 till 2010, inclusive.
>
> Then with C++11 the committee (I believe very reluctantly) partially
> gave up their absurd stance and let the standard allow the existing
> implementations of the language.


If I'd been in the room at the time, I would have self-immolated.

Siri Cruise

unread,
Jun 27, 2022, 7:59:20 PM6/27/22
to
In article
<756f4d86-7d99-4047...@googlegroups.com>,
Frederick Virchanza Gotham <cauldwel...@gmail.com> wrote:

> If I try to compile the following with the GNU compiler (g++):

If worse comes to worse, you can always use cpp and persnickety
placements of #defines and #includes to get around these problems.

#define static auto
#include "idiot's stupid variable declarations"
#undef static
#define static static

Not ideal, but you can make anything work. If you do have to do
this nonsense, be sure to add comments why.

And if even worse comes to cesspit worse. m4 is widely available
and can be coerced with pinhead's hooks and chains to do what cpp
cannot.

--
:-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted. @
'I desire mercy, not sacrifice.' /|\
Discordia: not just a religion but also a parody. This post / \
I am an Andrea Chen sockpuppet. insults Islam. Mohammed

Juha Nieminen

unread,
Jun 28, 2022, 2:52:13 AM6/28/22
to
Gawr Gura <gawr...@mail.hololive.net> wrote:
> On this the C++ standard says
>
> ...the contents of each header cname is the
> same as that of the corresponding header name.h as specified in
> the C standard library (Clause 2). In the C++ standard library,
> however, the declarations (except for names which are defined as
> macros in C) are within namespace scope (6.4.5) of the namespace
> std. It is unspecified whether these names (including any
> overloads added in Clause 17 through Clause 33 and Annex D) are
> first declared within the global namespace scope and are then
> injected into namespace std by explicit using-declarations
> (9.9).
>
> You can find this in section 16.4.2.3
>
> Given that the language of the standard says that it is unspecified
> whether values from the c prefixed headers (like cstddef) are declared
> in the global scope I would say this is not a bug.

AFAIK it's a compromise by the standard because they don't want to
overburden the standard library implementations, or something.

But I think it's a bad compromise. It's making the life of the standard
library implementors easier at the cost of making the life of C++
programmers harder. If you #include <cstddef> you cannot assume that
the names are in the global namespace but you have to take into
account that they could be. Good luck remembering every single
name in all the <c...> header files.

On top of that, IIRC you can't assume <stdlib.h> exists, so no luck
in trying to make sure that those names *are* in the global namespace.
(Although I think C++23 "undeprecates" those headers, so if you wait
for it to become widely supported you can make sure.)

Alf P. Steinbach

unread,
Jun 28, 2022, 4:19:39 AM6/28/22
to
Uh, where did you get that idea?

The ".h" headers were formally deprecated in 1998, the first standard,
because the committee unwisely, I'd say retardedly, assumed that the
intent of the clean "c..." headers would be fully supported and adopted.

That didn't happen, and will now never happen, since the committee
backed down a little from their high academic stance in 2011.

Likewise, it will never happen that the ".h" headers will disappear.

C++'s success is entirely founded on C compatibility, on leveraging C
libraries. That will not change. You can count on that much more than
you could count on core language features like `throw` specifications
and `export`-ed templates.


> so no luck
> in trying to make sure that those names *are* in the global namespace.

For C++11 names from the C library just include the relevant ".h"
header, very simple.


> (Although I think C++23 "undeprecates" those headers, so if you wait
> for it to become widely supported you can make sure.)

A simple remedy is to always include both of pair, "c..." and ".h".

That provides full guarantees about where the C++11 and earlier names
from the C library are defined, namely in both namespace `std` and the
global namespace. Guarantees that one can RELY on.

Unfortunately the committee didn't entirely give up their academic pipe
dream, and in C++14, C++17 and no doubt also in C++20, new names such as
`std::byte` and C11 esoteric math functions, were introduced in "c..."
headers only, with explicit exceptions that these names should not be
provided by ".h" headers. Sabotaging things just to score points for a
f...ing academic ideal. Politics everywhere, it's frustrating to have
the C++ standardization committee prioritize internal political goals to
that degree (one member even argued that Bjarne is to blame for all the
recent bad decisions, I think his words were "Bjarne is the problem").


- Alf

Paavo Helde

unread,
Jun 28, 2022, 5:33:34 AM6/28/22
to
27.06.2022 17:37 Frederick Virchanza Gotham kirjutas:
> If I try to compile the following with the GNU compiler (g++):
>
> #include <cstddef>
>

namespace MyGreatProject {

> class size_t {
>
> };

} // namespace

Problem solved.

Öö Tiib

unread,
Jun 28, 2022, 5:49:25 AM6/28/22
to
It wasn't retarded but carefully lobbied by likes of MicroSoft to get rid
of competitors like Watcom and Borland. Maybe some academics
were fooled but there never was hope. C++ headers are never defining
interface of module. So two modules written in C++ but compiled with
different version of compiler or different compiling options were never
designed to be possible to link together without using C headers as
mediator. Nothing to talk of other programming languages. So even if
there are some libraries written in C++ these either are open source
or pretend to be C libraries for to be useful.

Juha Nieminen

unread,
Jun 28, 2022, 9:25:45 AM6/28/22
to
Alf P. Steinbach <alf.p.s...@gmail.com> wrote:
>> On top of that, IIRC you can't assume <stdlib.h> exists,
>
> Uh, where did you get that idea?

I expressed it a bit poorly.

The <*.h> headers being deprecated means that it's not guaranteed that
they will exist in a future version of the standard.

So while yes, you can be sure that they exist eg. in C++11, you can't
be sure they will exist in some hypothetical future C++35 (and thus
your code may break if compiled in that mode).

OTOH the committee apparently relented with C++23 and will
"undeprecate" those headers, so you can use them without the fear
of them suddenly disappearing...

Juha Nieminen

unread,
Jun 28, 2022, 9:27:19 AM6/28/22
to
Way to write confusing code inside that namespace...

David Brown

unread,
Jun 28, 2022, 9:27:24 AM6/28/22
to
In all real compiler and library implementations of C++, the same
toolchain is both a C and a C++ compiler, and the library and headers
are shared where possible. But sometimes you just have a C compiler
without C++ - to the greatest possible extent, the C library and headers
of an implementation are a subset of the C++ library and headers. That
means the C++ committee do not mess with the contents of <math.h> or
<stdlib.h> except when it is unavoidable - it saves implementers
littering the files with "#ifdef __cplusplus ..." sections.

So when new maths functions were introduced, there were two options -
either the C committee also wanted them and they could go in <math.h>
(and therefore also <cmath>), or the C folks did not want them and the
C++ gang had to put them in their own header. It would, IMHO, have made
more sense to have a new C++ specific header with the new functions
rather than adding them to <cmath>, but I haven't bothered to follow the
discussions and reasoning behind the decision.

Alf P. Steinbach

unread,
Jun 28, 2022, 11:10:02 AM6/28/22
to
Agreed, except that "more sense" is far too weak.

Like, it would perhaps have made "more sense" for the electric engine of
a hybrid car to be separate from the gas engine, so that it wouldn't
have to needlessly expend its power on driving the latter's pistons.

Note: I was apparently wrong about C++14 above and about the math
functions stemming from C11. Even though my copy of the final draft of
C++14 is not searchable, I think even a manual inspection should have
found some wording about exclusions of stuff from ".h" headers. But,
apparently this all started with C++17; sorry, dis-information!


- Alf

Paavo Helde

unread,
Jun 28, 2022, 1:18:55 PM6/28/22
to
Yes, the OP complaint was that the compiler does not allow him to write
confusing code.
0 new messages