为什么MSVS允许NULL作为纯虚函数说明符

why MSVS allows NULL as pure virtual function specifier?

本文关键字:函数 说明符 MSVS 允许 NULL 为什么      更新时间:2023-10-16

考虑以下程序:

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

但是当我在msvs2010上尝试它时,它编译了&运行的很好。我认为g++ &Clang在这件事上是对的。标准是怎么说的?我也使用Za命令行选项禁用了编译器扩展,但MSVS仍然接受该代码。为什么没有错误呢?

我也尝试了在线vc++编译器在这里,已于2015年7月8日最后更新。这真的是msvs2010中的bug吗?2015?

根据MSDN, NULL被定义为足够接近0的东西,以便msvc++吞下。就是这样。

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

NULL指定为实现定义的c++空指针常量,该常量是求值为0的整型常量表达式或std::nullptr_t类型的右值。因此,00Lnullptr都是NULL的有效实现。

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

9.2 类成员中的语法说明如下:

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

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

我们可以从18.2:

看到这一点

宏NULL是本国际标准194

中实现定义的c++空指针常量。

脚注说:

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

和section 4.10说:

空指针常量是值为0的整型文字(2.14.2)

排除(void*)0

clang和MSVC的早期版本接受其他整数字面值,但看起来clang在最新版本中修复了这个问题。