【问题标题】:Unexpected compiler behavior when declaring array of variable size [duplicate]声明可变大小数组时出现意外的编译器行为[重复]
【发布时间】:2015-03-24 22:01:12
【问题描述】:

所以,我正在向一名学生教授基本 C 编程以进行测试。

说到数组声明,我告诉他:

“你可以这样做”

int myArray[10];

-> 告诉他代码可以编译

“你也可以这样做”

#define ARRAY_SIZE 10
[...]
int myArray[ARRAY_SIZE];

-> 告诉他代码可以编译

“但你不能这样做!”

int arraySize = 10;
int myArray[arraySize];

-> 告诉他代码不会编译......但它确实可以编译!

myWholeLifeIsALie.jpg

我在 MinGW 中使用 DevC++。

汗,我打开Linux,做了一个简单的测试程序

#include <stdio.h>

int main()
{
  int size;
  int i;

  scanf("%d", &size);

  int array[size];

  for(i = 0; i < size; i++)
    array[i] = i*2;

  return 0;
}

它可以使用 g++ 和 gcc 编译和运行。

相反,MS Visual Studio 2010 编译器告诉我他“期望常量表达式”。这也是我对 g++/gcc 的期望。

我想我在这里遗漏了一些愚蠢的东西,但我什至不能......

【问题讨论】:

  • Does “int size = 10;” yield a constant expression? ... gccclang 的可能副本支持 VLA 作为 C++ 中的扩展,但 Visual Studio 不支持。
  • C 和 C++ 是不同的语言。
  • 正如@YuHao 指出的那样,您的问题表明您使用的是C++ 编译器,但您也用C 标记,这没有多大意义。尤其是在这种情况下,因为 C 和 C++ 在这方面是不同的。
  • 我使用 C (gcc) 和 C++ (g++) 对其进行了测试,因此我使用 C 和 C++ 进行了标记。我通常使用 C++ 工作,所以我不知道 C 的“特性”。顺便说一句,g++ 似乎很有魅力。
  • 除了上面所说的一切之外,在教授编程语言时,您必须绝对确保您(和学生)根据 C 标准进行编译。对于 gcc,您可以使用 gcc -std=c11 -pedantic-errors -Wall 执行此操作,其中 -std=c11 可以替换为您正在教授的标准。如果你不知道 C90、C99 和 C11 之间的区别,那么也许你不应该教 C 编程......

标签: c++ c arrays gcc variable-length-array


【解决方案1】:

不,先生,您的WholeLifeIsNotALie.jpg 也在那里。 :-)

是的,这在C 中是可能的。鉴于您的编译器支持C99,它允许称为VLA [可变长度数组]。

我对@9​​87654325@ 了解不多,但如果它正式支持,它应该在最新标准中定义的某个地方,否则支持作为编译器扩展提供。

旁注:您应始终检查scanf() 的返回值以确保正确输入。否则,你可能会遇到奇怪的事情。

【讨论】:

  • 尽管 C11 “允许” VLA,但它被标记为可选功能,因此符合标准的实现可能不支持它。无论如何,C99 100% 正确。
  • g++ 也会编译它。 g++ 不会自动调用 cc1plus 和所有与 C++ 相关的东西吗?换句话说,它不是以 C++ 的方式处理所有事情吗?
  • g++ 支持这个作为扩展。它不是标准的 C++。
  • @il_mix:g++ 的默认模式是支持 GNU 扩展(尤其是 VLA)。您可以通过 -std-pedantic 标志指定符合 C++ 标准行为(不包括 VLA 之类的任何内容)。
  • @2501: C11 6.10.8.3/p1 (formative) 将__STDC_NO_VLA__ 定义为"The integer constant 1, intended to indicate that the implementation does not support variable length arrays or variably modified types."
【解决方案2】:

标准 C++ 不支持可变长度数组(长度由变量的运行时值确定)。

但是,自 1999 年以来,标准 C 就支持它们。一些早于 1999 年的 C 编译器和一些 C++ 编译器支持 VLA(或类似功能)作为扩展。

一些编译器产品/套件(例如 gcc)具有选择对特定 C 或 C++ 标准的支持的选项,并且可以选择它们的挑剔程度(例如它们针对哪些构造发出诊断或警告)。

有必要阅读您的编译器文档,了解它默认支持哪些标准或特定于供应商的语言功能、如何更改这些以及如何发布诊断信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-06
    • 2012-01-20
    • 1970-01-01
    • 2021-09-18
    • 2013-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多