为什么MSVS允许NULL作为纯虚函数说明符
why MSVS allows NULL as pure virtual function specifier?
考虑以下程序:
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
类型的右值。因此,0
、0L
或nullptr
都是NULL
的有效实现。
Clang和GCC版本可能将其定义为0L
或nullptr
,而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在最新版本中修复了这个问题。
相关文章:
- 为什么转换函数声明不需要至少一个定义类型说明符
- NOEXCEPT 函数调用运算符的说明符_Not_fn
- 函数模板签名中忽略的成员类型def 的访问说明符
- 具有多个模板说明符的函数
- 在回调中使用函数时,C++未知重写说明符
- 是否可以要求虚函数使用C++"覆盖"说明符?
- 警告:函数使用不带尾随返回类型的'auto'类型说明符
- 缩短成员函数作用域说明符(嵌套类)(C++)
- 创建模板函数的每个实例时,模板函数类型定义说明符是否会正确内联?
- gmock - 如何使用 noexcept 说明符模拟函数
- 什么是带有友元说明符的析构函数
- 使用最终类说明符时,最终函数说明符是否冗余?
- C++14 使用捕获说明符递增 lambda 函数内部的值
- 析构函数在 lambda 捕获说明符中声明的类实例上运行两次
- 是复制构造函数中初始值设定项列表中的make_unique不使用noexcept说明符的好用途
- C2694 在析构函数上,当基类成员的析构函数具有非空 noexcept 说明符和主体时
- 构造函数C++异常说明符
- 为什么MSVS允许NULL作为纯虚函数说明符
- 如何使用内联函数说明符"hide"私有成员函数?
- 模板参数作为函数说明符和编译器优化