【问题标题】:Is a pointer to an array of unknown size incomplete?指向未知大小数组的指针是否不完整?
【发布时间】:2014-09-22 05:11:37
【问题描述】:

3.9/6 N3797:

[...]

指向未知大小数组的指针的类型,或已定义的类型 通过 typedef 声明为未知大小的数组,不能 完成。

听起来指向未知大小数组的指针是不完整的类型。如果是这样,我们就不能定义一个指向未知大小数组的指针对象。但这不是真的,因为我们可以定义一个未知边界的数组。

#include <iostream>

using std::cout;
using std::endl;

int (*a)[] = (int(*)[])0x4243afff;

int main()
{

}

它编译得很好。

DEMO

如果它是不完整的类型,我们就无法做到这一点。确实: 3.9/5:

对象不应被定义为具有不完整的类型

标准之前定义的不完整类型如下3./5:

已声明但未定义的类,枚举类型 某些上下文(7.2),或未知大小或不完整的数组 元素类型,是一个未完全定义的对象类型。 未完全定义的对象类型和 void 类型不完整 类型 (3.9.1)。

这意味着指向不完整类型的指针是完整的。矛盾?

那么我的推理哪里错了?

【问题讨论】:

  • 为什么你认为你不能有一个指向不完整类型的指针?
  • 曾经写过像“typedef struct list { void *value; struct list *nxt; } list”这样的链表结构吗?
  • 那不是数组。这只是一个内存地址。
  • “指向”不完整类型的指针类型本身就是完整类型。但是,我们不能将int (*a)[] 的类型更改为int (*)[5]。我认为,这就是标准想要用“无法完成”来表达的意思。
  • 如果你想引用标准,至少要把你的章节号弄对。

标签: c++ arrays pointers


【解决方案1】:

我认为这个措辞是有缺陷的。在您的代码中:

 int (*a)[];

a 的类型实际上是完整的。 *a 的类型不完整。在我看来(正如 dyp 在 cmets 中所说),引用的意图是说在程序的后面,*a 不可能是具有完整类型的表达式。

背景:一些不完整的类型可以稍后完成,例如正如 cdhowie 和 dyp 所建议的那样:

extern int a[];
int b = sizeof a;  // error
int a[10];
int c = sizeof a;  // OK

但是int (*a)[];以后不能完成; sizeof *a 永远是一个错误。

【讨论】:

  • 像“给定一个指向未知大小数组的指针,或者一个 typedef 声明为一个未知大小的数组,数组类型无法完成”这样的措辞可能会提高清晰度。 (尽管它可能仍会使用一些措辞调整。)
  • 并且,为了给读者提供一个例子,在这种情况下我们所说的“无法完成”的意思是你以后不能给出数组的大小。例如,给定声明int a[];,此类型不完整但可以完成——您可以稍后指定int a[10]; 以完成该类型。但是鉴于声明int (*a)[];,您以后无法完成*a 的类型——int (*a)[10]; 将是一个错误。 *a 注定永远拥有不完整的类型int[]
  • @cdhowie 我认为extern int a[]; 可能会更好,因为它是一个法律声明。
  • @dyp 实际上,我更多地考虑类型本身,而不是声明它们裸露的有效性。现在想这些东西已经太晚了。 :X
  • @MattMcNabb 我对“完成到”概念有误解。类型A稍后补全为B表示声明extern A a;和定义B b;声明并定义相同类型的变量。对吗?
【解决方案2】:

与 C++ 语句一样,英语句子必须在上下文中进行解释。引用句子的上下文使其含义非常清楚。该段内容为(§3.9 [basic.types]/p6,您引用的句子以粗体显示):

类类型(例如“class X”)可能在某一时刻不完整 一个翻译单元,稍后完成;类型“class X”是 两个点的类型相同。数组对象的声明类型可能 是一个不完整类类型的数组,因此不完整;如果 类类型稍后在翻译单元中完成,数组 类型变得完整;这两点的数组类型相同 类型。数组对象的声明类型可能是 大小未知,因此在翻译中的某一点不完整 单元并稍后完成;这两点的数组类型 (“T 的未知边界数组”和“N T 的数组”)不同 类型。 指向未知大小数组的指针的类型,或类型 由typedef 声明定义为未知大小的数组, 无法完成。

在上下文中阅读,很明显,“指向 T 的未知边界数组的指针”不能以对象声明的方式“完成”为“指向 N T 数组的指针”作为“T 的未知边界数组”可以稍后定义为“N 数组 T

【讨论】:

  • “引用句子的上下文使其含义非常清楚。” 从 OP 之前的问题猜测,我假设 OP 知道上下文但没有还是不明白那句话。此外,该引用并没有告诉我们指针类型本身是否不完整。
  • 嗯,这显然是一个关于理解“完成”在这里意味着什么的问题。如果我完成了某件事,它之前一直是不完整的,但是那种不完整与3.9/5中定义的不一样。我确实认为这令人困惑,至少有一点。我不认为 3.9/6 中的上下文清楚地指出了这种差异。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-12
  • 2022-01-02
  • 1970-01-01
  • 2014-07-22
  • 1970-01-01
相关资源
最近更新 更多