why ::size_t and ::ptrdiff_t aren't undefined in <cstddef>

P

PengYu.UT

std::size_t and std::ptrdiff_t are defined in <cstddef>.

I've noticed that a bunch of old math function in the global namespace
are undefined in <cmath> and they are redefined in std namespace.

I'm wondering why ::size_t and ::ptrdiff_t aren't undefined.

Thanks,
Peng
 
V

Victor Bazarov

std::size_t and std::ptrdiff_t are defined in <cstddef>.

I've noticed that a bunch of old math function in the global namespace
are undefined in <cmath> and they are redefined in std namespace.

I'm wondering why ::size_t and ::ptrdiff_t aren't undefined.

I can't find any specific mention of std::ptrdiff_t. Are you sure that
that type is in the 'std' namespace?

IIRC, it was discussed several times, and the conclusion is that it is
generally quite a task to keep (a) <cHHHH> and <HHHH.h> headers in sync
and (b) ready for inclusion by both C and C++ translation units. That
is why often while the requirement is in <cHHHH> to only declare those
functions/types in 'std' namespace, the global definitions do slip in.

V
 
J

Jack Klein

std::size_t and std::ptrdiff_t are defined in <cstddef>.

I've noticed that a bunch of old math function in the global namespace
are undefined in <cmath> and they are redefined in std namespace.

I'm wondering why ::size_t and ::ptrdiff_t aren't undefined.

Thanks,
Peng

When you include any of the 18 C standard headers that are included in
the C++ standard, you can do so in two ways:

#include <stddef.h>

....or:

#include <cstddef>

This applies to every one of the C headers.

When you include a C header the first way, the same way as you would
in C, the C++ standard requires that each identifier that can be
scoped be defined in both the global and std namespace.

When you include a C header the second way, that is 'c' in front and
without the ".h" at the end, the C++ standard requires that each such
identifier be defined in the std namespace only, and not in the global
namespace.

The issue here is that this particular requirement of the C standard
is not highly regarded by many. Quite a few compiler vendors put some
of all of the C identifiers in the global namespace even when the
headers are included with the preferred C++ syntax. They think they
will get too many complaints from user about breaking existing code.

There is another possibility. The C++ standard allows any standard
header to include any other standard headers. There are, or at least
have been, some C++ implementations where some C++ standard headers
include C headers, often stddef.h, with the C syntax, thus putting
those names into the global namespace.

Technically, this is a violation of the standard, but it is unlikely
to get much attention from the implementers.
 
P

PengYu.UT

Victor said:
I can't find any specific mention of std::ptrdiff_t. Are you sure that
that type is in the 'std' namespace?
Yes. You can read the file cstddef by yourself.
IIRC, it was discussed several times, and the conclusion is that it is
generally quite a task to keep (a) <cHHHH> and <HHHH.h> headers in sync
and (b) ready for inclusion by both C and C++ translation units. That
is why often while the requirement is in <cHHHH> to only declare those
functions/types in 'std' namespace, the global definitions do slip in.

If cmath chooses to undef the old definitions, for consistency, should
cstddef also undefine old definitions as well?
 
P

P.J. Plauger

When you include any of the 18 C standard headers that are included in
the C++ standard, you can do so in two ways:

#include <stddef.h>

...or:

#include <cstddef>

This applies to every one of the C headers.

When you include a C header the first way, the same way as you would
in C, the C++ standard requires that each identifier that can be
scoped be defined in both the global and std namespace.

When you include a C header the second way, that is 'c' in front and
without the ".h" at the end, the C++ standard requires that each such
identifier be defined in the std namespace only, and not in the global
namespace.

The issue here is that this particular requirement of the C standard
is not highly regarded by many. Quite a few compiler vendors put some
of all of the C identifiers in the global namespace even when the
headers are included with the preferred C++ syntax. They think they
will get too many complaints from user about breaking existing code.

No, the reasons go much deeper than that.
There is another possibility. The C++ standard allows any standard
header to include any other standard headers. There are, or at least
have been, some C++ implementations where some C++ standard headers
include C headers, often stddef.h, with the C syntax, thus putting
those names into the global namespace.

Technically, this is a violation of the standard, but it is unlikely
to get much attention from the implementers.

No, it's not.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
V

Victor Bazarov

Yes. You can read the file cstddef by yourself.

Well, it can be educational to read "the file cstddef", but it is more
educational to read the Stadnard. The contents of _your_ cstddef can very
well be different from the contents of _my_ cstddef. [Not to mention that
standard headers don't have to be implemented as files]
If cmath chooses to undef the old definitions, for consistency, should
cstddef also undefine old definitions as well?

I don't know. The Standard does say that <cHHHH> should declare
everything in 'std' namespace, while <HHHH.h> should have both 'std' and
globally declared variations for each standard symbol. There is nothing
in the Standard about _un_declaring anything.

Again, it *has* been discussed before, look in the archives. The result
as I see it, of those discussions, is that it's fairly difficult to do
what the Standard asks, so some symbols (like 'size_t', for example) can
sometimes fall through. It could be seen as a bug or it could be seen as
a sign of things to come. Ask in comp.std.c++ about that.

V
 
G

Greg Comeau

I can't find any specific mention of std::ptrdiff_t. Are you sure that
that type is in the 'std' namespace?

See 17.4.3.1.4
IIRC, it was discussed several times, and the conclusion is that it is
generally quite a task to keep (a) <cHHHH> and <HHHH.h> headers in sync
and (b) ready for inclusion by both C and C++ translation units. That
is why often while the requirement is in <cHHHH> to only declare those
functions/types in 'std' namespace, the global definitions do slip in.

This probably hits home why although the underlying reason
for blah.h vs cblah was noble and "the right thing to do"
that in practice it was a mistake. So while there is lots
of noise over say export, IMO, these are some of the real
issues which need to be addressed (and to be fair, they are
being addressed).
 
G

Greg Comeau

When you include any of the 18 C standard headers that are included in
the C++ standard, you can do so in two ways:

#include <stddef.h>

...or:

#include <cstddef>

This applies to every one of the C headers.

When you include a C header the first way, the same way as you would
in C, the C++ standard requires that each identifier that can be
scoped be defined in both the global and std namespace.

When you include a C header the second way, that is 'c' in front and
without the ".h" at the end, the C++ standard requires that each such
identifier be defined in the std namespace only, and not in the global
namespace.

The issue here is that this particular requirement of the C standard
is not highly regarded by many.

Not sure what this mean, as I have never heard this to be the case.
Quite a few compiler vendors put some
of all of the C identifiers in the global namespace even when the
headers are included with the preferred C++ syntax. They think they
will get too many complaints from user about breaking existing code.

This is an issue, but probably not the top most one, that probably
being the consideration of the various forms of implementations out
there.
There is another possibility. The C++ standard allows any standard
header to include any other standard headers. There are, or at least
have been, some C++ implementations where some C++ standard headers
include C headers, often stddef.h, with the C syntax, thus putting
those names into the global namespace.

Technically, this is a violation of the standard, but it is unlikely
to get much attention from the implementers.

Neither of these points seem to be true. I suspect we may be
cross talking past the same issue somehow...
 
J

Jack Klein

[snip something obviously complete wrong...]

Since both P.J. Plauger and Greg Comeau tell me I'm wrong in
comp.lang.c++, I'm willing to throw in the towel. Ignore my previous
post.
 
H

Howard Hinnant

Jack Klein said:
[snip something obviously complete wrong...]

Since both P.J. Plauger and Greg Comeau tell me I'm wrong in
comp.lang.c++, I'm willing to throw in the towel. Ignore my previous
post.

Well, if you are wrong, it looks like a defect in the standard to me.
17.4.1.1p2 says:
-2- All library entities except macros, operator
new and operator delete are defined within the
namespace std or namespaces nested within namespace std.

Admittedly it does not say "and nowhere else". But reading that
paragraph with the lack of "and nowhere else" and interpreting that to
mean "and anywhere else you please" is stretching things pretty far imho.

That being said, there is also a proposal before the C++ committee to
standardize the widespread practice of "leaking" the C names to global:

http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#456

The status of this proposal is "Open" meaning that it has not yet been
decided upon one way or the other.

-Howard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,754
Messages
2,569,522
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top