当前位置: 首页 > 知识库问答 >
问题:

GNU编译器与Visual Studio在范围内分配有长度常量的数组上的比较

梅安平
2023-03-14

我知道,如果您在c/c中设置了一个动态值,则无法使用括号中的该值来分配数组(这将使其成为当前c标准不支持的所谓可变长度数组(VLA))…

即,请参阅:
c:variable length arrayhttp://en.wikipedia.org/wiki/Variable-length_array

我不太明白的(以及我在这里没有看到确切询问的)是为什么GNU c / c编译器(gccg)可以使用基于整数值的动态分配(据我所知),只要该值是数组分配范围内的常量,但Visual Studio不支持这一点,并且会拒绝编译代码, 吐出错误。

例如,以 g 为单位

void Foo(const unsigned int bar)
{
  double myStuff[bar];
  //... do stuff...
}

…编译得很好。。。

但是同样的代码拒绝在我使用的VS版本中编译,除非我传递给bar的任何内容在所有范围内都是const,或者是#define静态const等。

我怀疑也许GNU编译器使用这个范围来推断这个值是该范围内的常量,然后简单地将其分配给malloc或以某种方式专门处理它。

我的问题是:

  1. 就如何处理这个问题而言,谁(VS或GNU)更接近标准
  2. 有没有一种方法可以在整个程序中使用[]对作用域内的常量值进行VS,而不是全局常量malloc调用
  3. 如果我在GNU编译的代码中使用它,有什么问题需要注意吗

共有2个答案

赵俊远
2023-03-14

GNU编译器集合支持可变长度数组作为扩展,使用-pedantic编译,您将看到预期的警告。

#include <iostream>

int main()
{
    int foo = 10;
    int bar[foo];
}

编译:

g++-4.8 -std=c++11 -O2 -pedantic -pthread main.cpp && ./a.out
main.cpp: In function ‘int main()’:
main.cpp:6:16: warning: ISO C++ forbids variable length array ‘bar’ [-Wvla]
     int bar[foo];
                ^
刘和昶
2023-03-14

从语言的角度来看,VLA仅在C中受支持,并且仅在C99之后受支持。C 中不支持它们。

从编译器的角度来看,g将支持vla作为C90和C的扩展,但是如果你用< code>-pedantic编译,它将禁用那些扩展,你将得到一个编译错误。

Visual Studio在C或C中都不支持VLA。VS只支持C89标准,AFAIK MS也没有计划支持更高的C标准。

就范围而言,这是在C标准中定义的:

VLA不能被声明为静态或在文件范围内是有技术原因的;具有静态存储持续时间的对象在程序启动时被分配并保持到程序终止,如果我没有弄错的话,它不能保证对象会以任何特定的顺序被分配和初始化。所以这些项目需要在编译时知道它们的大小。

 类似资料:
  • 我最近发现龙目山。jar最终会出现在我们的最终工件中,这应该是不必要的。在我看来,lombok只是编译时的。 但是当我将它设置为提供的范围时,我在单元测试中会遇到奇怪的行为。当试图解决时,它们会与ClassNotFoundExceptions崩溃 龙目山通常使用哪种maven范围? 我在MacOSX 10.9上使用Oracle JDK build 1.8.0_25-b17

  • 当构造函数参数使用 val 声明时,下面的代码失败 作品: 不工作: 编译器给出错误: Scala编译器中的错误:类型不匹配;找到:java.lang.Object必需:array[java.lang.Object] 而不能给出行号。

  • 问题内容: 我有一个表,例如此数据 我想有一个查询,将日期分开,所以我有像这样一年中分开的金额: 2013年有25个月是因为2013年有1个月,而2014年有75个月是因为有3个月 有没有办法在T-SQL中做到这一点? 提前谢谢! 问题答案: 使用表格创建日历表格,然后将其加入表格以将日期范围划分为所需的任何部分。 如果按年份除以金额,然后除以月份,您可以: 这是SQL FIDDLE DEMO。

  • 问题内容: 假设我有一个这样的课程: 我的应用程序中的许多其他类都在使用这些选项。现在,我只想更改其中一个选项,而仅部署已编译的类。但是,如果将这些字段插入到消费者类中,这将变得不可能,对吗? 是否有任何选项可以禁用内联编译时间常数? 问题答案: 您可以使用String.intern()获得所需的效果,但应注释您的代码,因为对此知之甚少。即 这样可以防止内联编译时间。由于它是指编译器将放入烫发中的

  • 问题内容: 有没有办法获取所有当前在javascript范围内的变量? 问题答案: 否。“范围内”变量由“作用域链”确定,该变量无法通过编程方式访问。 有关详细信息(很多),请查看ECMAScript(JavaScript)规范。这是指向官方页面的链接,您可以在其中下载规范规范(PDF),而这是指向官方的可链接HTML版本的链接。 根据您对Camsoft的评论进行更新 事件函数作用 域中 的变量取

  • 问题内容: 假设有一个与此问题类似的情况。我想得到以下结果: 我可以使用选定的答案作为解决方案: 我如何确保即使在该范围内没有任何结果,也将显示30-39的分数范围? 问题答案: 尝试以下查询(也在SQL Fiddle上): 编辑: 您可以通过将参数更改为轻松调整范围。可以使用以下构造来确保始终覆盖您的分数: 对于CTE。