Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No ::nullptr_t in header <stddef.h> #37564

Open
llvmbot opened this issue Jul 19, 2018 · 9 comments
Open

No ::nullptr_t in header <stddef.h> #37564

llvmbot opened this issue Jul 19, 2018 · 9 comments
Labels
bugzilla Issues migrated from bugzilla c++11 clang:headers Headers provided by Clang, e.g. for intrinsics

Comments

@llvmbot
Copy link
Collaborator

llvmbot commented Jul 19, 2018

Bugzilla Link 38216
Version unspecified
OS Linux
Reporter LLVM Bugzilla Contributor
CC @DougGregor,@mclow,@zygoloid,@jwakely

Extended Description

clang++ rejects the following code:

#include <stddef.h>

::nullptr_t n;

"3|error: 'nullptr_t' in namespace '::' does not name a type"

This code is supposed to be accepted, because [depr.c.headers] p2 says:

"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."

Paolo Carlini has suggested to perform this change near to existing C++11-aware code in stddef.h:

#if (defined (STDC_VERSION) && STDC_VERSION >= 201112L)
|| (defined(__cplusplus) && __cplusplus >= 201103L)
#ifndef _GCC_MAX_ALIGN_T
#define _GCC_MAX_ALIGN_T
/* Type whose alignment is supported in every context and is at least
as great as that of any standard type not using alignment
specifiers. /
typedef struct {
long long __max_align_ll attribute((aligned(alignof(long long))));
long double __max_align_ld attribute((aligned(alignof(long double))));
} max_align_t;
#endif
#endif /
C11 or C++11. */

BTW, I tried g++. It accepts the above code sample.

@zygoloid
Copy link
Mannequin

zygoloid mannequin commented Jul 19, 2018

Clang++ accepts when using libc++.

The problem is that we added this in libc++, whereas GCC added it in their compiler-specific stddef.h wrapper.

Question is, who should change? Should libstdc++ change, in that it's not providing a correct C++ standard library implementation when used with a C standard library <stddef.h>? Or should Clang change, to provide this little piece of the C++ standard library itself rather than relying on the C++ stdlib to do it?

(We already make the latter choice on Windows platforms, where the native <stddef.h> apparently also lacks ::nullptr_t.)

@jwakely
Copy link
Mannequin

jwakely mannequin commented Jul 19, 2018

IMHO nullptr_t should only have been required by and not <stddef.h>. That's what we did for std::byte. Too late now though.

Libstdc++ could provide its own <stddef.h> which uses #include_next <stddef.h> (which would either find GCC's one, or the C library one) but I'd really prefer not to.

We do that for <math.h> and <stdlib.h> and it causes problems too often (when somebody does -I /usr/include the include order changes and #include_next no longer works).

@jwakely
Copy link
Mannequin

jwakely mannequin commented Jul 19, 2018

A simpler libstdc++ change would be to just add it to the global namespace unconditionally in <bits/c++config.h>, which is where we add it to namespace std, not in .

I think that would be conforming, since any std::lib header is allowed to include and it's unspecified whether that adds its names to just namespace std or also the global namespace.

I don't much like that, but would be less unhappy if it was conditional:

--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -251,6 +251,12 @@ namespace std
#endif
}

+#if clang
+// GCC's <stddef.h> defines ::nullptr_t but Clang uses a different <stddef.h>
+// that might not define it. Ensure it's present in the global namespace:
+using std::nullptr_t;
+#endif
+
#define _GLIBCXX_USE_DUAL_ABI

#if ! _GLIBCXX_USE_DUAL_ABI

@jwakely
Copy link
Mannequin

jwakely mannequin commented Jul 19, 2018

ICC has the same problem, but that's not your concern.

@zygoloid
Copy link
Mannequin

zygoloid mannequin commented Jul 19, 2018

We do that for <math.h> and <stdlib.h> and it causes problems too often
(when somebody does -I /usr/include the include order changes and
#include_next no longer works).

libc++ does this for 18 of the C headers; doing so seemed necessary to get the right results for the headers where C and C++ have somewhat different requirements (for instance, we are required to #undef macros that the C headers "helpfully" define that shadow libc functions). We don't consider ourselves responsible for problems caused by people misconfiguring their own include paths.

@jwakely
Copy link
Mannequin

jwakely mannequin commented Sep 29, 2020

IMHO nullptr_t should only have been required by and not
<stddef.h>. That's what we did for std::byte. Too late now though.

Maybe it's not too late, there seems to be support for removing it.
https://wg21.link/lwg3484

@mclow
Copy link
Contributor

mclow commented Sep 29, 2020

IMHO nullptr_t should only have been required by and not
<stddef.h>. That's what we did for std::byte. Too late now though.

Maybe it's not too late, there seems to be support for removing it.
https://wg21.link/lwg3484

There's usually support for removing things from people who won't get the bug reports when code using it breaks ;-)

That being said, we have implementation divergence, and we should resolve that.

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 10, 2021
@jwakely
Copy link
Contributor

jwakely commented Dec 27, 2021

IMHO nullptr_t should only have been required by and not <stddef.h>. That's what we did for std::byte. Too late now though.

This is supposed to say "should only have been required by <cstddef> and not <stddef.h>" but the imported plain text comments from bugzilla are now treated as markdown (which is quite annoying).

@ldionne
Copy link
Member

ldionne commented Jan 3, 2022

@jwakely I read the original bug report and I'm wondering what's expected from Clang/libc++ here. It seems like the simplest fix would be for libstdc++ to declare nullptr_t inside <stddef.h>. Is there something actionable for LLVM here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla c++11 clang:headers Headers provided by Clang, e.g. for intrinsics
Projects
None yet
Development

No branches or pull requests

5 participants