【问题标题】:Pointers to VLA's指向 VLA 的指针
【发布时间】:2019-04-20 21:45:10
【问题描述】:

如您所知,VLA's haves pros and cons 在 C11 中是可选的。

我认为让 VLA 可选的主要原因是:“堆栈会爆炸”:

int arr[n]; /* where n = 1024 * 1024 * 1024 */

但是指向 VLA 的指针呢?

int m, n;

scanf("%d %d", &m, &n);

int (*ptr)[n] = malloc(sizeof(int [m][n]));

在这种情况下,没有炸毁堆栈的风险,而且 IMO 它们非常有用。

我的问题是:

委员会能否保留指向 VLA 的指针,使 VLA 指向非指针类型是可选的?

或者一件事暗示另一件事?

(请原谅我的英语不好)

【问题讨论】:

  • 它不是 PC,但我认为让 VLA 成为可选的主要原因是让 MS 可以假装他们有一个符合标准的编译器
  • int (*ptr)[n] 只是一个指向大小为n 的数组的指针。这里的n 可以被编译器完全忽略,因为它没有任何用途。 int *ptr; 完全一样。
  • @PaulOgilvie - n 会影响指针运算在 ptr 上的执行方式。绝对不容忽视。
  • ptr + x 必须等于 (char*)ptr + x * (sizeof(int[n])) - 数组中的常用指针运算。就像行大小是一个常量表达式一样。在这种情况下,它不是。
  • 全部清除。非常感谢。

标签: c variable-length-array


【解决方案1】:

保留指向可变可修改类型的指针需要实现支持大约 90% 的 VLA 规范。原因是有效的类型规则:

6.5 表达式

¶6 访问其存储值的对象的有效类型 是对象的声明类型(如果有)。如果一个值被存储到 没有通过具有类型的左值声明的类型的对象 不是字符类型,则左值的类型变为 该访问和后续的对象的有效类型 不修改存储值的访问。如果一个值被复制 使用 memcpy 或 memmove 进入没有声明类型的对象,或者是 复制为字符类型的数组,然后是有效类型 为该访问和后续访问修改的对象 不修改值是从中的对象的有效类型 该值被复制,如果它有一个。对于所有其他访问 没有声明类型的对象,对象的有效类型是 只是用于访问的左值的类型。

通过ptr访问malloced内存后,对象的有效类型为VLA类型。因此,实现将需要正确支持这些语义。唯一可以保留“可选”的是能够声明具有自动存储持续时间的 VLA...

int boo[n];

... 这有点傻。如果实现支持动态分配对象的大多数 VLA 语义,它还可以允许将它们声明为具有自动存储持续时间的对象。委员会希望它是真正可选的,这意味着指向 VLA 类型的指针也必须删除。

【讨论】:

  • 我认为这个答案不正确。除了基于非别名执行优化之外,实现有效的类型规则根本没有任何工作,实现者可以省略他们喜欢的任何规则,因为这些规则适用于符合要求的应用程序而不是实现。另一方面,自动存储 VLA 必然与低级后端交互。
  • @R.. - 问题是关于标准的 pov。围绕有效类型规则需要修改和削减的规范数量在我看来并非微不足道。当然实现可以实现任何东西。
  • 引用几乎无关紧要,因为您永远不能将具有数组类型的值存储到对象中——您只能将具有数组元素类型的值存储到数组的元素中。同样,您永远不能访问具有数组类型的值——只能访问数组的元素。我认为 StoryTeller 的评论确定了主要原因。
猜你喜欢
  • 2017-05-15
  • 2015-04-15
  • 2015-06-17
  • 2019-05-13
  • 2014-09-22
  • 2011-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多