On Fri, May 09, 2025 at 10:31:38AM +0800, LIU Hao wrote: > 在 2025-5-4 22:24, наб 写道: > > Consider the following program, reduced from Lensfun: > > #include <cstring> > > extern char *f(const char *first_element, ...) > > __attribute__((__sentinel__)); > > static auto N = f("a", "b", NULL); > > static auto n = f("a", "b", nullptr); > > static auto z = f("a", "b", 0); > > #define NULL 123 > > in C++11 and later, NULL=nullptr so N/n are valid, and z is wrong. > > In C++ it's common to have `NULL` defined as `0`. This is not the case. I think I was a little overzealous to say that "C++11 <=> NULL=nullptr" (both C and C++ allow any "null-pointer constant"), but both GCC and Clang define it as __null.
GCC: 77395be63213 (Richard Stallman 1992-03-30 02:25:19 +0000 413) #if defined (_STDDEF_H) || defined (__need_NULL) 301264e6e9f7 (Michael Meissner 1991-11-27 20:06:32 +0000 414) #undef NULL /* in case <stdio.h> has defined it. */ 7a389b48df6a (Jason Merrill 1996-08-08 01:45:02 +0000 415) #ifdef __GNUG__ 7a389b48df6a (Jason Merrill 1996-08-08 01:45:02 +0000 416) #define NULL __null 7a389b48df6a (Jason Merrill 1996-08-08 01:45:02 +0000 417) #else /* G++ */ be78ffb2267d (Jason Merrill 2000-06-24 18:19:46 -0400 418) #ifndef __cplusplus 301264e6e9f7 (Michael Meissner 1991-11-27 20:06:32 +0000 419) #define NULL ((void *)0) be78ffb2267d (Jason Merrill 2000-06-24 18:19:46 -0400 420) #else /* C++ */ be78ffb2267d (Jason Merrill 2000-06-24 18:19:46 -0400 421) #define NULL 0 be78ffb2267d (Jason Merrill 2000-06-24 18:19:46 -0400 422) #endif /* C++ */ 7a389b48df6a (Jason Merrill 1996-08-08 01:45:02 +0000 423) #endif /* G++ */ 77395be63213 (Richard Stallman 1992-03-30 02:25:19 +0000 424) #endif /* NULL not defined and <stddef.h> or need NULL. */ 77395be63213 (Richard Stallman 1992-03-30 02:25:19 +0000 425) #undef __need_NULL $ git show 7a389b48df6a commit 7a389b48df6a1622eb12ad09d5def385f357734b Author: Jason Merrill <merr...@gnu.org> Date: Thu Aug 8 01:45:02 1996 +0000 (NULL): Use __null for G++. From-SVN: r12601 diff --git a/gcc/ginclude/stddef.h b/gcc/ginclude/stddef.h index 49c2556e001..0cea45972da 100644 --- a/gcc/ginclude/stddef.h +++ b/gcc/ginclude/stddef.h @@ -306,7 +306,11 @@ typedef __WINT_TYPE__ wint_t; #if defined (_STDDEF_H) || defined (__need_NULL) #undef NULL /* in case <stdio.h> has defined it. */ +#ifdef __GNUG__ +#define NULL __null +#else /* G++ */ #define NULL ((void *)0) +#endif /* G++ */ #endif /* NULL not defined and <stddef.h> or need NULL. */ #undef __need_NULL Clang: 272bcf6768d3c (Nico Weber 2014-04-30 04:35:09 +0000 102) #if defined(__need_NULL) 0a4a8326c1027 (Ted Kremenek 2010-03-08 23:23:45 +0000 103) #undef NULL 95aa0b77f25c8 (Argyrios Kyrtzidis 2013-03-27 21:22:45 +0000 104) #ifdef __cplusplus 1d725ecf93037 (Nico Weber 2012-04-24 21:27:01 +0000 105) # if !defined(__MINGW32__) && !defined(_MSC_VER) 1d725ecf93037 (Nico Weber 2012-04-24 21:27:01 +0000 106) # define NULL __null 1d725ecf93037 (Nico Weber 2012-04-24 21:27:01 +0000 107) # else 1d725ecf93037 (Nico Weber 2012-04-24 21:27:01 +0000 108) # define NULL 0 1d725ecf93037 (Nico Weber 2012-04-24 21:27:01 +0000 109) # endif 6b0dc8511964e (Anders Carlsson 2008-11-04 06:53:14 +0000 110) #else 1d725ecf93037 (Nico Weber 2012-04-24 21:27:01 +0000 111) # define NULL ((void*)0) 6b0dc8511964e (Anders Carlsson 2008-11-04 06:53:14 +0000 112) #endif 72da678d8c84c (Ian Anderson 2023-08-11 14:38:13 -0700 113) #undef __need_NULL 72da678d8c84c (Ian Anderson 2023-08-11 14:38:13 -0700 114) #endif /* defined(__need_NULL) */ commit 1d725ecf93037e8877286f53a7289f39064a9fc5 Author: Nico Weber <tha...@chromium.org> Date: Tue Apr 24 21:27:01 2012 +0000 Let NULL and MSVC headers coexist better. Fixes the two issues mentioned in PR12146. llvm-svn: 155490 diff --git a/clang/lib/Headers/stddef.h b/clang/lib/Headers/stddef.h index 9e87ee89b3b9..d7db826e676e 100644 --- a/clang/lib/Headers/stddef.h +++ b/clang/lib/Headers/stddef.h @@ -43,10 +43,13 @@ typedef __WCHAR_TYPE__ wchar_t; #undef NULL #ifdef __cplusplus -#undef __null // VC++ hack. -#define NULL __null +# if !defined(__MINGW32__) && !defined(_MSC_VER) +# define NULL __null +# else +# define NULL 0 +# endif #else -#define NULL ((void*)0) +# define NULL ((void*)0) #endif #define offsetof(t, d) __builtin_offsetof(t, d) 0a4a8326c1027 (Ted Kremenek 2010-03-08 23:23:45 +0000 44) #undef NULL 6b0dc8511964e (Anders Carlsson 2008-11-04 06:53:14 +0000 45) #ifdef __cplusplus 38321174e09cd (Chris Lattner 2010-08-03 22:13:56 +0000 46) #undef __null // VC++ hack. f7ab50df29066 (Douglas Gregor 2008-12-01 17:20:57 +0000 47) #define NULL __null 6b0dc8511964e (Anders Carlsson 2008-11-04 06:53:14 +0000 48) #else 9e9b046ac95c9 (Eli Friedman 2008-05-20 13:34:26 +0000 49) #define NULL ((void*)0) 6b0dc8511964e (Anders Carlsson 2008-11-04 06:53:14 +0000 50) #endif $ git show f7ab50df29066 commit f7ab50df290663597d02b8a5668866bfb57fc989 Author: Douglas Gregor <dgre...@apple.com> Date: Mon Dec 1 17:20:57 2008 +0000 Define NULL to __null in C++, so that it's guaranteed to have the same size as a pointer llvm-svn: 60355 diff --git a/clang/lib/Headers/stddef.h b/clang/lib/Headers/stddef.h index d5f4eb9c7c29..2c84b4b066c9 100644 --- a/clang/lib/Headers/stddef.h +++ b/clang/lib/Headers/stddef.h @@ -33,7 +33,7 @@ typedef __typeof__(*L"") wchar_t; #endif #ifdef __cplusplus -#define NULL (0) +#define NULL __null #else #define NULL ((void*)0) #endif This has been the case since 1996, and since 2012 Clang includes a work-around the very bug I'm trying to fix in this patch. > Your code should not > assume `NULL` is an expression whose size is a pointer. This is code found in the wild that obeys the convention followed by every other distribution, and there's no reason mingw-w64 should diverge. Even /if/ this weren't the case, mingw-w64 /already/ uses the conventional #define NULL __null in /some/ headers, but not others. Even /if/ this is legal, having inconsistent NULL values is undesirable and fixing it to be consistent is also a good goal. Please reconsider.
signature.asc
Description: PGP signature
_______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public