3.9 / 6 N3797:
[...]
指向未知大小或已定义类型的数组的指针类型 通过typedef声明成为未知大小的数组,不可能 完成。
听起来像指向未知大小的数组的指针是不完整的类型。如果是这样,我们就无法定义指向未知大小数组的指针的对象。但事实并非如此,因为我们可以定义一个未知界限的数组。
#include <iostream>
using std::cout;
using std::endl;
int (*a)[] = (int(*)[])0x4243afff;
int main()
{
}
它汇编得很好。
如果它是不完整的类型我们不能这样做。确实: 3.9 / 5:
不应将对象定义为具有不完整类型
标准以前定义了一个不完整的类型如下:3/5:
已声明但未定义的类,其中包含枚举类型 某些上下文(7.2),或者一个未知大小或不完整的数组 元素类型,是一种未完全定义的对象类型。 未完全定义的对象类型和void类型不完整 类型(3.9.1)。
这意味着指向不完整类型的指针已完成。矛盾?
所以我的推理错了?
答案 0 :(得分:6)
我认为这个措辞有缺陷。在您的代码中:
int (*a)[];
a
的类型实际上已完成。 *a
的类型不完整。在我看来(正如dyp在评论中所说),引用的意图是说在程序的后期没有办法,*a
将是一个完整类型的表达式。
背景:一些不完整的类型可以在以后完成,例如正如cdhowie和dyp所建议的那样:
extern int a[];
int b = sizeof a; // error
int a[10];
int c = sizeof a; // OK
但int (*a)[];
以后无法完成; sizeof *a
永远是一个错误。
答案 1 :(得分:0)
与C ++语句一样,英语句子必须在上下文中解释 。引用句子的语境使其含义非常清楚。该段落为(§3.9[basic.types] / p6,您引用的句子加粗):
类类型(例如“
class X
”)可能在某一点上不完整 翻译单位,稍后完成;类型“class X
”是 两点都是相同的类型。声明的数组对象类型可能 是一个不完整类类型的数组,因此不完整;如果 类类型稍后在转换单元中完成 类型变得完整;这两点的数组类型是一样的 类型。声明的数组对象类型可能是数组 未知的大小因此在翻译中的某一点不完整 单位并在稍后完成;这两点的数组类型 (“T
的未知界限数组”和“N T
数组”不同 类型。 指向未知大小或类型的数组的指针类型 由typedef
声明定义为未知大小的数组, 无法完成。
在上下文中读取,显然说“指向T
未知范围的数组的指针”无法“完成”到“指向N T
数组的指针”中声明为“T
”未知范围的数组的对象以后可以定义为“N T
数组”