[libcxx-commits] [libcxx] [libc++] Simplify the implementation of <stddef.h> (PR #86843)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Mon Jul 15 08:17:24 PDT 2024


ldionne wrote:

I think I have convinced myself that libc++ isn't to blame here. Before this PR, the way libc++ included `stddef.h` prevented this issue from getting to users whenever they had libc++ headers on the search path (which is most of the time), but fundamentally the problem seems to be happening in the Clang builtin headers.

Reproducer:

```shell
cat <<EOF | clang++ -nostdinc++ -std=c++11 -xc++ - -v -fsyntax-only --trace-includes
#define NULL nullptr
#include <stddef.h> // NULL gets redefined inside that header

static_assert(__is_same(decltype(NULL), decltype(nullptr)), "");
EOF
```

Output:

```
#include <...> search starts here:
 <...>/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/16/include
 <...>/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include
 <...>/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
 <...>/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks (framework directory)
End of search list.

. <...>/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/16/include/stddef.h
.. <...>/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/16/include/__stddef_header_macro.h
.. <...>/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/16/include/__stddef_ptrdiff_t.h
.. <...>/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/16/include/__stddef_size_t.h
.. <...>/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/16/include/__stddef_wchar_t.h
.. <...>/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/16/include/__stddef_null.h
.. <...>/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/16/include/__stddef_nullptr_t.h
.. <...>/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/16/include/__stddef_max_align_t.h
.. <...>/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/16/include/__stddef_offsetof.h

<stdin>:4:15: error: static assertion failed due to requirement '__is_same(long, std::nullptr_t)':
    4 | static_assert(__is_same(decltype(NULL), decltype(nullptr)), "");
      |               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```

Furthermore, if I additionally add `-nobuiltininc` to the above command-line in order to stop searching in the Clang builtin headers, the `NULL` macro is not redefined and I get the following header trace:

```
. <...>/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/stddef.h
.. <...>/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_types.h
... <...>/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types.h
.... <...>/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/cdefs.h
..... <...>/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_symbol_aliasing.h
..... <...>/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_posix_availability.h
.... <...>/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/machine/_types.h
..... <...>/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/arm/_types.h
.... <...>/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_pthread/_pthread_types.h
.. <...>/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_null.h
etc
```

Hence, it looks like the Clang builtin headers today completely override any platform-provided `<stddef.h>` and they exhibit this behavior of always redefining `NULL` to `__null`. It certainly seems incorrect to me that the Clang builtin headers are overriding the platform-provided `<stddef.h>` -- I don't think that behavior is useful.

However, I also think that users are not allowed to define `NULL` to their liking and I don't think we should try to support that. So basically, IMO we should clarify the situation w.r.t. the role of the Clang builtin headers and determine whether they are currently overstepping on the platform (I think they are), but fundamentally the `NULL` redefinition example isn't something that should be expected to work (and AFAICT it doesn't work on Linux).

https://github.com/llvm/llvm-project/pull/86843


More information about the libcxx-commits mailing list