在 C23 之前如何使用“nullptr”作为空指针?

问题描述 投票:0回答:1

在 C23 中,

nullptr
关键字 得到了标准化。在 C23 之前,我也更喜欢使用
nullptr
而不是
NULL
,因为这意味着我可以编写可在以下位置编译的代码:

  • C,先于 C23
  • C,自 C23
  • C++

据我所知,不允许使用

#define
来替换语言中的关键字,这可能会在定义兼容性宏时导致问题。基本上,我需要:

// only if this is neither C++ nor C23
#define nullptr /* something */

如何正确定义这个宏?

c c-preprocessor c23
1个回答
2
投票

可以通过预定义宏来检测您是否使用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

参见编译器资源管理器中的实时示例

© www.soinside.com 2019 - 2024. All rights reserved.