【问题标题】:why MSVS allows NULL as pure virtual function specifier?为什么 MSVS 允许 NULL 作为纯虚函数说明符?
【发布时间】:2016-01-06 08:32:01
【问题描述】:

考虑以下程序:

struct Test
{
    virtual void foo()=NULL;
};
int main()
{ }

g++ 4.8.1 给出如下预期错误:

[Error] invalid pure specifier (only '= 0' is allowed) before ';' token

Clang 给出以下错误:

error: initializer on function does not look like a pure-specifier

但是当我在 MSVS 2010 上尝试它时,它编译并运行良好。我认为 g++ & clang 在这种情况下是正确的。标准对此有何规定?我也使用 \Za 命令行选项禁用了编译器扩展,但 MSVS 仍然接受该代码。为什么它没有给出任何错误?

我还在 Online VC++ Compiler here 上尝试过,它最后一次更新是在 2015 年 7 月 8 日。这真的是 MSVS 2010 和 2015 中的错误吗?

【问题讨论】:

  • Pure virtual functions in C++11 无效,好像是个bug。
  • @ShafikYaghmour:那么,有没有为此提交错误报告?
  • @PravasiMeet 我怀疑 VS2010 刚刚将 NULL 定义为 0
  • @ShafikYaghmour:最好提交错误报告。
  • 我犯了一个错误,这不是一个错误,但它不会跨平台保持一致,因为它取决于 NULL 的定义。

标签: c++ visual-studio-2010 syntax pure-virtual function-declaration


【解决方案1】:

根据MSDNNULL 被定义为与0 足够接近以供MSVC++ 吞下的东西。就是这样。

尝试在该代码之前执行#undef NULL,它应该会正确中断编译。

【讨论】:

  • 我认为该链接仅适用于 C,(void*)0 不是 C++ 中 NULL 的有效定义。
  • @TartanLlama 但又一次,因为 MSVC++ 关心这一点:)
  • 哈,没错。我认为它需要定义为0 才能编译代码。即使是 MSVC 也不够野蛮接受= ((void*) 0)(我希望)。
  • 查看我的 MSVC 安装的标头,如果定义了 __cplusplus,则将其定义为 0,否则定义为 ((void *)0),它完全符合标准。
  • 好吧,我的回答的第二部分仍然有效。定义为0 会更加明显。
【解决方案2】:

NULL 被指定为实现定义的 C++ 空指针常量,它是一个整数常量表达式,其值为零或std::nullptr_t 类型的纯右值。因此,00Lnullptr 都是NULL 的有效实现。

您的 Clang 和 GCC 版本可能将其定义为 0Lnullptr,而您的 MSVC 版本将其定义为 0。在这种情况下,预处理器会将NULL 替换为0,从而使您的程序结构良好。

【讨论】:

    【解决方案3】:

    9.2类成员部分的语法如下:

    [...]
    member-declarator:
     declarator virt-specifier-seqopt pure-specifieropt
    [...]
    pure-specifier:
      = 0
      ^^^
    

    所以纯说明符必须是文字0NULL 最有可能被定义为 MSVC 的 0,但它不必定义为 0,另一种可能性是 0L,这是语法不允许的,这可能是 gcc 和 clang 使用的。

    我们可以从18.2部分看到这一点:

    宏 NULL 是本国际标准 194 中实现定义的 C++ 空指针常量

    脚注说:

    可能的定义包括 0 和 0L,但不包括 (void*)0。

    4.10 部分说:

    空指针常量是一个值为零的整数文字 (2.14.2)

    排除(void*)0

    clang 和 MSVC accepted other integer literals 的早期版本,但看起来 clang 在最新版本中修复了这个问题。

    【讨论】:

      猜你喜欢
      • 2016-07-06
      • 1970-01-01
      • 2023-03-27
      • 2011-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多