4

I see that Microsoft's stddef.h defines nullptr_t thus:

namespace std
{
    typedef decltype(__nullptr) nullptr_t;
}

using ::std::nullptr_t;

The using decleration injects nullptr_t into the global namespace. I can't find anything in the standard that says that this should be done.

I also see that in GCC nullptr_t isn't in the global namespace.

Can both implementations be allowed or is one of them a bug? My bad, GCC behaves the same as CL.


Edit: The same happens with cstddef, the following compiles fine with VC (online too).

#include <cstddef>

int main()
{
    nullptr_t nil = nullptr;
}
5
  • Is there a difference betweeen using ::std::nullptr_t; and using std::nullptr_t;? Nice question btw.
    – gsamaras
    Commented Oct 13, 2015 at 11:19
  • @gsamaras I don't think there's a difference.
    – Motti
    Commented Oct 13, 2015 at 11:40
  • There's no difference in this context. There is a difference if you have namespace foo { namespace std { using nullptr_t = int } using std::nullptr_t; }. Commented Oct 13, 2015 at 11:41
  • GCC does define it in the global namespace: gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/ginclude/… Commented Oct 13, 2015 at 11:41
  • @JonathanWakely, oops, you're right.
    – Motti
    Commented Oct 13, 2015 at 11:43

2 Answers 2

8

It must be in the global namespace.

D.5 C standard library headers [depr.c.headers]

2 Every C header, each of which has a name of the form name.h, behaves as if each name placed in the standard library namespace by the corresponding cname header is placed within the global namespace scope. [...]

There is no exception here for names that are specific to C++. If C++ adds a name to <cstddef> that C's <stddef.h> doesn't provide, then C++'s <stddef.h> still needs to provide it too.

2
  • It's also injected into the global namespace for <cstddef>.
    – Motti
    Commented Oct 13, 2015 at 11:40
  • 1
    @Motti Yes, that's allowed. The <cxxx> headers must define names in the std namespace, and may also define them in the global namespace. The <xxx.h> headers must define them in the global namespace, and may also define them in the std namespace.
    – user743382
    Commented Oct 13, 2015 at 11:42
2

I also see that in GCC nullptr_t isn't in the global namespace.

Are you sure about that?

https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/ginclude/stddef.h;hb=HEAD#l436

You might have an older version of GCC, I see it there for GCC 4.8.0 and later.

The same happens with cstddef,

That's not guaranteed to work. To use ::nullptr_t portably you must include <stddef.h>. To use std::nullptr_t portably you must include <cstddef>.

Not the answer you're looking for? Browse other questions tagged or ask your own question.