[PATCH] D12747: Implement [depr.c.headers]

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 6 15:57:51 PDT 2015


<stddef.h>. This one is tricky:

1) There's an (undocumented) interface between the C standard library and
this header, where the macros __need_ptrdiff_t, __need_size_t,
__need_wchar_t, __need_NULL, __need_wint_t request just a piece of this
header rather than the whole thing. If we see any of those, just go
straight to the underlying header.

2) We probably don't want <stddef.h> to include <cstddef> (for consistency
with other headers), but <stddef.h> must provide a ::nullptr_t (which we
don't want <cstddef> to provide). So neither header includes the other.
Instead, both include <__nullptr> for std::nullptr_t, and we duplicate the
definition of max_align_t between them, in the case where the compiler's
<stddef.h> doesn't provide it.

If you prefer, I could make <stddef.h> include <cstddef> to avoid the
duplication of the max_align_t logic.

This patch depends on patch 02.

On Tue, Oct 6, 2015 at 3:42 PM, Richard Smith <richard at metafoo.co.uk> wrote:

> <setjmp.h>, an easy one. We guarantee a setjmp macro exists even if this
> header is somehow included from C (the C standard allows that, so it's not
> worth checking for __cplusplus).
>
> On Tue, Oct 6, 2015 at 3:36 PM, Richard Smith <richard at metafoo.co.uk>
> wrote:
>
>> Split <math.h> out of <cmath>. This is a big change, but the same pattern
>> as the prior ones.
>>
>> On Tue, Oct 6, 2015 at 3:28 PM, Richard Smith <richard at metafoo.co.uk>
>> wrote:
>>
>>> Likewise for <errno.h>, <float.h>, <inttypes.h>
>>>
>>> On Tue, Oct 6, 2015 at 3:20 PM, Richard Smith <richard at metafoo.co.uk>
>>> wrote:
>>>
>>>> Split <ctype.h> header out of <cctype>
>>>>
>>>> On Tue, Oct 6, 2015 at 3:07 PM, Richard Smith <richard at metafoo.co.uk>
>>>> wrote:
>>>>
>>>>> Next: factoring the definition of std::nullptr_t out into a separate
>>>>> file, so that <cstddef> and <stddef.h> can both use it, without <stddef.h>
>>>>> including <cstddef> and without <cstddef> providing a ::nullptr_t like
>>>>> <stddef.h> does.
>>>>>
>>>>> On Tue, Oct 6, 2015 at 3:02 PM, Eric Fiselier <eric at efcs.ca> wrote:
>>>>>
>>>>>> LGTM.
>>>>>>
>>>>>> On Tue, Oct 6, 2015 at 3:58 PM, Richard Smith <richard at metafoo.co.uk>
>>>>>> wrote:
>>>>>> > On Mon, Oct 5, 2015 at 7:10 PM, Eric Fiselier <eric at efcs.ca> wrote:
>>>>>> >>
>>>>>> >> EricWF added a comment.
>>>>>> >>
>>>>>> >> I think thing change will help us close a number out outstanding
>>>>>> bugs. I
>>>>>> >> don't have any fundamental objections to this approach.  However
>>>>>> the size of
>>>>>> >> this patch scares me.  I understand the changes are mostly
>>>>>> mechanical but
>>>>>> >> their size can hide things. For example has anybody noticed that
>>>>>> your
>>>>>> >> internal changes to `<deque>` are in this patch? It would be nice
>>>>>> to break
>>>>>> >> this down into more digestible pieces that could be quickly spot
>>>>>> checked.
>>>>>> >
>>>>>> >
>>>>>> > OK. First such patch is attached. It just removes the
>>>>>> macro-capturing
>>>>>> > wrapper functions.
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20151006/42a53788/attachment.html>
-------------- next part --------------
diff --git include/cstddef include/cstddef
index 68f52c2..1210b91 100644
--- include/cstddef
+++ include/cstddef
@@ -34,10 +34,10 @@ Types:
 */
 
 #include <__config>
+// Don't include our own <stddef.h>; we don't want to declare ::nullptr_t.
+#include_next <stddef.h>
 #include <__nullptr>
 
-#include <stddef.h>
-
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
diff --git include/stddef.h include/stddef.h
new file mode 100644
index 0000000..6ffe582
--- /dev/null
+++ include/stddef.h
@@ -0,0 +1,56 @@
+// -*- C++ -*-
+//===--------------------------- stddef.h ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__need_ptrdiff_t) || defined(__need_size_t) || \
+    defined(__need_wchar_t) || defined(__need_NULL) || defined(__need_wint_t)
+#include_next <stddef.h>
+
+#elif !defined(_LIBCPP_STDDEF_H)
+#define _LIBCPP_STDDEF_H
+
+/*
+    stddef.h synopsis
+
+Macros:
+
+    offsetof(type,member-designator)
+    NULL
+
+Types:
+
+    ptrdiff_t
+    size_t
+    max_align_t
+    nullptr_t
+
+*/
+
+#include <__config>
+#include_next <stddef.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#ifdef __cplusplus
+
+extern "C++" {
+#include <__nullptr>
+using std::nullptr_t;
+}
+
+// Re-use the compiler's <stddef.h> max_align_t where possible.
+#if !defined(__CLANG_MAX_ALIGN_T_DEFINED) && !defined(_GCC_MAX_ALIGN_T)
+typedef long double max_align_t;
+#endif
+
+#endif
+
+#endif  // _LIBCPP_STDDEF_H
diff --git test/std/depr/depr.c.headers/stddef_h.pass.cpp test/std/depr/depr.c.headers/stddef_h.pass.cpp
index 140c91b..c03c314 100644
--- test/std/depr/depr.c.headers/stddef_h.pass.cpp
+++ test/std/depr/depr.c.headers/stddef_h.pass.cpp
@@ -10,6 +10,7 @@
 // <stddef.h>
 
 #include <stddef.h>
+#include <cassert>
 #include <type_traits>
 
 #ifndef NULL
@@ -22,6 +23,9 @@
 
 int main()
 {
+    void *p = NULL;
+    assert(!p);
+
     static_assert(sizeof(size_t) == sizeof(void*),
                   "sizeof(size_t) == sizeof(void*)");
     static_assert(std::is_unsigned<size_t>::value,
@@ -34,4 +38,22 @@ int main()
                   "std::is_signed<ptrdiff_t>::value");
     static_assert(std::is_integral<ptrdiff_t>::value,
                   "std::is_integral<ptrdiff_t>::value");
+    static_assert(std::is_same<decltype(nullptr), nullptr_t>::value,
+                  "decltype(nullptr) == nullptr_t");
+    static_assert(sizeof(nullptr_t) == sizeof(void*),
+                  "sizeof(nullptr_t) == sizeof(void*)");
+    static_assert(std::is_pod<max_align_t>::value,
+                  "std::is_pod<max_align_t>::value");
+    static_assert((std::alignment_of<max_align_t>::value >=
+                  std::alignment_of<long long>::value),
+                  "std::alignment_of<max_align_t>::value >= "
+                  "std::alignment_of<long long>::value");
+    static_assert(std::alignment_of<max_align_t>::value >=
+                  std::alignment_of<long double>::value,
+                  "std::alignment_of<max_align_t>::value >= "
+                  "std::alignment_of<long double>::value");
+    static_assert(std::alignment_of<max_align_t>::value >=
+                  std::alignment_of<void*>::value,
+                  "std::alignment_of<max_align_t>::value >= "
+                  "std::alignment_of<void*>::value");
 }


More information about the cfe-commits mailing list