【问题标题】:Why is clang defining NULL as __null?为什么clang将NULL定义为__null?
【发布时间】:2019-11-04 17:09:54
【问题描述】:

我有一个 .cpp 文件,它在多个地方都使用了 NULL。当我尝试在 Windows 机器 + 独立工具链上使用 clang++ 为 Android/x86 平台编译这个 cpp 文件时,我在使用 NULL 的地方遇到了“预期表达式”错误。我在 Android NDK 提供的 clang 标头的 stddef.h 中找到了 NULL 的定义,如下所示。

#if defined(__need_NULL)
#undef NULL
#ifdef __cplusplus
#  if !defined(__MINGW32__) && !defined(_MSC_VER)
#    define NULL __null
#  else
#    define NULL 0
#  endif
#else
#  define NULL ((void*)0)
#endif

据我所知,__null 是特定于 GNU 编译器的。就我而言,_MSC_VER 和 __MINGW32__ 都未定义,因为我正在使用 clang++ 和独立工具链为 Android 平台进行编译。所以它进入了define NULL __null。由于 clang++ 不知道__null 是什么,因此导致“预期表达式”错误。

我的问题是,为什么 clang 使用 GNU 编译器提供的宏(如 __null)?还是我在这里遗漏了什么?

谁能帮我理解。谢谢

【问题讨论】:

  • 已经使用nullptr..
  • 什么独立的工具链?您也可以尝试添加-D__MINGW32__ 看看它是否有效..
  • 是的,确保没有人重新定义__null

标签: android c++ android-ndk clang++ llvm-clang


【解决方案1】:

为什么 clang 将 NULL 定义为 __null?

__null优于0,因为前者只是一个空指针常量,而后者也是一个整数常量。在重载解析和类型推导的情况下,这种差异很显着:

void foo(int);
void foo(void*);

foo(0);       // calls foo(int)
foo(__null);  // call is ambiguous, program is ill-formed
foo(NULL);    // could have either behaviour
              //  call to foo(int) would be undesirable
foo(nullptr); // calls foo(void*)

原因与在 C++11 中引入 nullptr 的原因相同或相似。

这样做的另一个原因是 clang 努力与 GCC 紧密兼容。

因为 clang++ 不知道 __null 是什么

clang++ appears 知道__null 是什么。

【讨论】:

  • 但是 __null gnu 不是特定的吗?为什么在 clang 代码中使用它? clang 将如何了解 gnu 编译器的特定宏?
  • @Pendyala Clang 支持许多 GNU 扩展。显然包括这个:godbolt.org/z/fsFNjP
  • 请查看godbolt.org/z/GihtJE。 clang 似乎不支持 __null。
  • @Pendyala 您的示例也无法在 GCC 中编译:godbolt.org/z/LO0URg
  • @Pendyata:要声明抽象虚方法,必须使用“= 0”。您没有分配指针。 "= NULL" 是不正确的 C++,无论编译器如何,也无论它是否恰好在某些编译器上工作。
猜你喜欢
  • 1970-01-01
  • 2019-02-25
  • 1970-01-01
  • 2012-01-12
  • 2019-01-31
  • 2021-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多