【发布时间】:2014-11-09 06:53:44
【问题描述】:
我正在标准中寻找对这一事实的正式解释。 我找到了 3.9.1/9 所说的内容,并尝试使用该部分进行解释。
第 3.9.1/9 节,N3797:
void 类型有一组空值。 void 类型是一个 无法完成的不完整类型。它被用作回报 不返回值的函数的类型。任何表达式都可以 显式转换为 cv void (5.4) 类型。 void 类型的表达式 应仅用作表达式语句(6.2),作为操作数 逗号表达式 (5.18),作为 ? 的第二个或第三个操作数:(5.16), 作为 typeid、noexcept 或 decltype 的操作数,作为 返回类型为 void 的函数的返回语句 (6.6.3), 或作为显式转换为 cv void 类型的操作数。
我不明白 void 类型具有一组空值这一事实意味着什么?
假设类型 T 有一组空值。为什么编译器遇到以下行时会抛出错误:
extern T v;
我们可以通过以下方式对不完整类型的变量进行 decal:
#include <iostream>
#include <cstring>
using namespace std;
struct Foo;
extern Foo f; //OK!
int main()
{
}
效果很好
它不能在 void 类型上完成
#include <iostream>
#include <cstring>
using namespace std;
extern void f; //compile-time error
int main()
{
}
【问题讨论】:
-
如果类型有一组空值,你可以用这个变量做什么?
-
它们的关键是“void 类型是一个不完整的类型无法完成”,这就是它与任何其他不完整类型的不同之处。
-
@K-ballo:
struct Foo是一个不完整的对象类型。void不是对象类型。这使得它在根本上有所不同。 -
@K-ballo:因为definition of object type 说不是。
-
@BenVoigt:隐式转换为
uintptr_t会启用一些奇怪的表达式,例如ptr + 1.0。对我来说,有一个“未指定地址”的类型是有意义的,尤其是在 C 中。但如果你要让它成为一个整数类型,我认为你应该需要在两个方向上进行强制转换。未拼写为void*的指针类型可能会满足所有小问题。
标签: c++ language-lawyer void