nullptr
关键字 得到了标准化。在 C23 之前,我也更喜欢使用 nullptr
而不是 NULL
,因为这意味着我可以编写可在以下位置编译的代码:
据我所知,不允许使用
#define
来替换语言中的关键字,这可能会在定义兼容性宏时导致问题。基本上,我需要:
// only if this is neither C++ nor C23
#define nullptr /* something */
如何正确定义这个宏?
可以通过预定义宏来检测您是否使用C23:
#if !__cplusplus && __STDC_VERSION__ < 202311
#define nullptr 0
#endif
但是,这样一个简单的宏会触发编译器警告(
clang -Wundef -std=c89
):
<source>:1:6: warning: '__cplusplus' is not defined, evaluates to 0 [-Wundef]
1 | #if !__cplusplus && __STDC_VERSION__ < 202311
| ^
<source>:1:21: warning: '__STDC_VERSION__' is not defined, evaluates to 0 [-Wundef]
1 | #if !__cplusplus && __STDC_VERSION__ < 202311
|
解决方案可以重写,这样就不会触发警告:
/* don't do anything in C++ */
#ifndef __cplusplus
#ifndef __STDC_VERSION__
/* define nullptr in C89, where __STDC__VERSION__ is not defined */
#define nullptr ((void*)0)
/* won't trigger -Wundef due to short circuiting */
#elif __STDC_VERSION__ < 202311L
/* define nullptr for all standards from C95 to C17 */
#define nullptr ((void*)0)
#endif
#endif
参见编译器资源管理器中的实时示例