【问题标题】:Does clang support __null?clang 支持 __null 吗?
【发布时间】:2019-11-06 18:17:20
【问题描述】:

当我使用 clang++ 5.0 版编译以下程序时,会导致

错误:函数的初始化器看起来不像纯说明符

extern void print(void *ptr);

#define NULL __null

class IInterface
{
public:
    virtual void method1() = NULL;
};


int main()
{
    void *ptr = NULL;
    print(ptr);
    return 0;
}

clang 好像不支持__null?但是stackoverflow中的一些帖子建议clang支持__null。如果是这样,为什么我会收到此错误。有人可以建议这里发生了什么吗?

链接:https://godbolt.org/z/-f3Kf9

【问题讨论】:

  • 你是 c++11 之前的吗?如果没有,为什么不使用nullptr?如果是,最好添加适当的标签
  • 这是一个 g++ 疣,这里 C++ 需要=0
  • 只要在任何地方使用nullptr。不要使用__null0NULL anywhere - 使用 nullptr 作为空指针常量。但是,为了声明一个纯垂直函数,语法是= 0,所以这就是你必须使用的。

标签: c++ c++14 clang++ llvm-clang


【解决方案1】:

纯虚函数的语法只有= 0。例如,virtual void do_stuff() = 0 是允许的,但 virtual void do_stuff() = nullptr 是不允许的。

Clang 确实支持__null,但编译器内部并不意味着声明虚函数。

NULL可能适用于纯虚函数的唯一原因是某些系统将其定义为0,但您不应该依赖它。一些编译器也可能使用0LL(void*)0

如果可以,您应该使用nullptr 而不是NULL 来声明空指针。这是最好的解决方案,可以在旧标准中效仿。

要声明纯虚函数,请使用= 0。这是声明纯虚函数的最简单常用的方法。

【讨论】:

  • 可能需要重新措辞;现在第一段似乎与最后一段相矛盾,直到你仔细观察
  • @Lightness...谢谢...所以 __null 是关键字?不是宏吗?在哪里可以看到它的定义?
  • 这不是一个真正的关键字,而是一个内部编译器。您通常可以识别出带有前导双取消线的那些。
  • @Pendyala 显然是it's an implementation detail (答案是关于 GCC 但 Clang 有一些类似的东西),所以......两者都不是。这当然不是标准的。我不知道你为什么选择使用它。
  • By the Holy Laws of C++,任何连续包含两个下划线的内容都是不可移植的实现细节,并且在您升级工具时可能会消失。那是一个潜在的编程错误,可能导致非常混乱的错误或运行时行为。
【解决方案2】:

这似乎是某种误解。将虚函数设为纯函数与将其初始化为空指针不同。事实上,一些编译器会将纯函数的 vtable 条目设置为指向名为 __cxa_pure_virtual 或类似名称的特殊函数。

由于您实际上并未初始化指针,因此您不能在此处使用__nullNot even GCC 4.1 allows it. 也不能使用nullptr,这是__null 的标准替换。在这里写= 0;

【讨论】:

  • 这是一个很好的例子,说明了为什么我认为整个 = 0 是误导性的。我意识到时间线是错误的,但[[pure]] 属性会更好。 (或者可能是其他名称)
  • @LightnessRaceswithMonica 我同意。话虽如此,在糟糕的 C++ 设计决策的宏伟计划中,这几乎不值得一个脚注。
  • 确实如此!
【解决方案3】:

这里发生了什么:

  1. 由于某种原因,您使用的是内部编译器 (__null) 而不是标准的 nullptr(最糟糕的是,旧的 NULL 已经在标准中,不需要您定义)

  2. 出于某种原因,您尝试使用__null(或NULL(或nullptr))作为纯虚函数说明符。你不能那样做。它应该是= 0。我相信 GCC 允许或曾经允许您作为扩展所做的事情; Clang 没有。

真的就这么简单!

接下来的步骤:

  1. 停止对空指针使用__null;请改用nullptr
  2. 停止对纯虚函数说明符使用空指针。我是= 0

【讨论】:

    猜你喜欢
    • 2014-05-14
    • 1970-01-01
    • 1970-01-01
    • 2015-03-01
    • 1970-01-01
    • 2015-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多