【问题标题】:Declaring an array on the stack in C (VS2015)在 C 中的堆栈上声明一个数组(VS2015)
【发布时间】:2016-02-23 10:40:09
【问题描述】:

我在尝试在 C 中声明堆栈上的数组时遇到了一个奇怪的问题。我一直认为(至少到现在为止)如果没有常量表达式就不可能在堆栈上声明数组。例如尝试在 Windows 上的 VS2015 上编译以下代码:

int main()
{
    int i = 3;
    int test[i];

    return 0;
}

会产生“表达式必须具有常量值”错误,这是我所期望的,但在 Linux 机器上使用 gcc 和 clang 编译相同的代码是可行的。起初我认为这可能是编译器推断的东西,所以我尝试了以下方法:

int main()
{
    int i = 3;
    int j = i*i;
    int test[j];

    return 0;
}

VS2015 再次抱怨同样的错误,但 gcc 和 clang 编译它就好了!我立刻想,好吧,也许那些编译器也在推断,毕竟只是“常量”表达式。所以我尝试了以下方法:

int main()
{
    int i = getchar();
    int test[i];

    return 0;
}

当然编译器无法推断这一点,i 用于声明 test 时的值只能在运行时知道,但令我惊讶的是,VS2015 再次抱怨,但 gcc 和 clang 编译了它.. . 甚至添加以下内容:

int main()
{
    int i = getchar();
    int test[i];

    printf("%d\n", sizeof(test) / sizeof(int));

    return 0;
}

在ASCII表中输入值为120的字符x,输出120。

发生了什么事?

【问题讨论】:

  • 这在技术上是可行的,因为数组位于栈顶。但我不打算使用这个功能。
  • int test[i]; 不会初始化数组 - int test[i] = {}; 会。我相信你的意思是“声明”。
  • @molbdnilo 谢谢,我会编辑
  • @UnTraDe 使用常识。你所有的 4 个例子都是完美的 C,在过去的 17 年里一直如此。然而,Visual Studio 会错误地给您错误和警告。至于来源,请参阅this。直到 2015 年,他们才升级为支持 1999 标准。据我所知,支持还远未完成。 VS 根本就不是一个好的 C 编译器。

标签: c arrays visual-studio gcc clang


【解决方案1】:

您遇到了 VLA(Variable-Length A射线)。
与“通常”的数组不同,它们采用 runtime 确定的值作为大小说明符。

由于VS2015主要支持C89,C99中引入了VLA,Visual Studio不支持,报错。

注意 VLA 是 C.C++ does not support them. 的一个特性@

【讨论】:

  • 正确。但请注意:此功能在 C11 中降级为可选。总结在这里:en.wikipedia.org/wiki/C11_%28C_standard_revision%29.
  • @david.pfx:从未要求编译器以特别有用的方式支持该功能。没有上下文(即使在顶级“main()”中,也需要符合要求的实现来保证任何特定大小(甚至单个元素)的 VLA 分配都会成功,也没有任何限制符合标准的实现可能会在失败的情况下执行。将它们放在一起,符合标准的编译器将被允许将任何分配 VLA 的尝试视为调用未定义的行为。高质量的编译器不应该以这种方式运行,但是...
  • ...最好允许编译器拒绝编译它们无法有效运行的代码,而不是要求它们接受代码但允许它们在执行时以任意方式运行。
  • @supercat:就是这样。另一个“当时听起来是个好主意”的案例,但现在可以帮助一些人并混淆其他人。最好不要依赖...
  • @david.pfx:我希望标准的作者能够更加强调对某些但不是所有实现有用的构造,并指定实现不需要支持这些构造,但必须拒绝任何他们不能支持的东西。恕我直言,应该编写实现和程序的标准来定义“选择性符合程序”,以便可以在 C 中完成的大多数任务都可以使用选择性符合程序来完成,但是任何符合此类程序的实现都需要处理它没有 UB(注意...
猜你喜欢
  • 2017-01-30
  • 2010-09-08
  • 1970-01-01
  • 2012-07-12
  • 2021-07-07
  • 2012-08-09
  • 2013-07-11
  • 2011-03-09
  • 2017-07-19
相关资源
最近更新 更多