【问题标题】:Does any major C++ implementation actually define `NULL` as `nullptr`?是否有任何主要的 C++ 实现实际上将 `NULL` 定义为 `nullptr`?
【发布时间】:2020-08-25 05:27:40
【问题描述】:

自 C++11 起,标准允许宏 NULL 为值为零的整数文字,或类型为 std::nullptr_t 的纯右值。

任何标准库供应商决定将其 NULL 的定义从整数更改为 nullptr 很可能会导致依赖 C++11 之前代码的客户端出现故障。

是否有任何主要实现(例如 GCC、Clang、MSVC)实际上将 NULL 定义为 nullptr 或者,尽管有可能,但没有人这样做?

【问题讨论】:

  • 您可以为您的工具链轻松确定这一点(实际上,对于所有三个)。您在获取这些信息时遇到了一些实际问题吗?
  • 如果将 NULL0L 更改为 nullptr 会破坏您的代码,恕我直言,您的代码一直被破坏。
  • @AsteroidsWithWings “与 C 共享”是什么意思?通常是 0L 用于 C++,(void*)0 用于 C 和 #ifndef __cplusplus
  • @Ayxan 啊,真的吗?不知道。
  • 作为参考,STL 有一个关于试图改变这一点并在他们自己的代码中遇到一堆问题的轶事:youtu.be/AKtHxKJRwp4?t=3437。 OTOH,几年后有this tweet,同一个人。

标签: c++ c++11 null c++-standard-library nullptr


【解决方案1】:

libstdc++relies on including stddef.h,定义NULL如下:

// <stddef.h>
//
#if defined (_STDDEF_H) || defined (__need_NULL)
#undef NULL     /* in case <stdio.h> has defined it. */
#ifdef __GNUG__
#define NULL __null
#else   /* G++ */
#ifndef __cplusplus
#define NULL ((void *)0)
#else   /* C++ */
#define NULL 0
#endif  /* C++ */
#endif  /* G++ */
#endif  /* NULL not defined and <stddef.h> or need NULL.  */
#undef  __need_NULL

关于__null的信息可以在this question找到:

__null 的实现是作为 G++ 内部的。基本上,内部执行您天真地期望reinterpret_cast&lt;void *&gt;(0) 执行的操作。

它的类型是“魔法”,取决于上下文。这就是 G++ 必须将其作为内部实现的原因。没有常规类型提供精确正确的语义。它的行为大致类似于 void *,但不完全一样。


libc++does pretty much the same thing:

// <cstddef>
//
// Don't include our own <stddef.h>; we don't want to declare ::nullptr_t.
#include_next <stddef.h>
#include <__nullptr>

微软的STL 也有relies on including stddef.h

#pragma once
#ifndef _CSTDDEF_
#define _CSTDDEF_
#include <yvals_core.h>
#if _STL_COMPILER_PREPROCESSOR

#include <stddef.h>

我在开源 STL 存储库中找不到stddef.h,但是vcruntime.h 中提供了NULL 的定义:

#ifndef NULL
    #ifdef __cplusplus
        #define NULL 0
    #else
        #define NULL ((void *)0)
    #endif
#endif

icc 19.0.1 的简单测试也表明NULL 没有定义为nullptr

#include <type_traits>
#include <cstddef>

static_assert(!std::is_same<decltype(NULL), std::nullptr_t>::value, "");
static_assert(!std::is_same<decltype(NULL), int>::value, "");
static_assert(std::is_same<decltype(NULL), long>::value, "");

live on godbolt.org

【讨论】:

    猜你喜欢
    • 2011-11-04
    • 2018-07-31
    • 2020-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-22
    • 2011-06-21
    • 1970-01-01
    相关资源
    最近更新 更多