C语言 海合会抱怨说:可能无法初始化可变大小的对象

hl0ma9xz  于 2022-12-26  发布在  其他
关注(0)|答案(3)|浏览(142)

我看过这些,它们没有回答我的问题:
variable-sized object may not be initialized
C compile error: "Variable-sized object may not be initialized"
Error: Variable-sized object may not be initialized. But why?
我正在尝试编写一些相当可移植的c代码:

int main () 
{
    const int foo=13;
    int bar[foo]={0};
    return 0;
}

使用以下任一项编译为'c'代码时,出现'可变大小对象可能无法初始化'错误:

*海合会第4.3.4条
*arm操作系统-操作系统-gnueabi-gcc 4.4.5

如果我在VS 2008中将其编译为c,则会得到一个略有不同的error C2057: expected constant expression
我知道,在这里,c代码编译器没有将const int foo=13;识别为真正的常量;例如我们可能有

void a(int fool) 
{    
    const int foo=fool;
    int bar[foo]={0};
}

我也意识到unlike the gcc compilersVS 2008编译器没有C99 variable-length arrays的概念,而且微软显然没有提到任何未来的支持。
然而,用gccMS编译器编译cpp代码完全不同/更聪明?!

关于gcc'c'代码编译器,还有 * 我不明白 * 的地方是:

  • 由于此代码 * 确实 * 编译,
int main () 
{
    int bar[13]={0};
    return 0;
}
  • 为什么这个代码 * 不 * 编译..
int main()
{
    const int foo=13; //cpp compiler knows this really is const ! 
    int bar[foo]={0};
    return 0;
}
  • 但这段代码编译吗
int main()
{
    const int foo=13;  
    int bar[foo+1]={0}; //wtF?
    return 0;
}

(NB:在最后一种情况下,MSc代码编译失败;与int bar[foo]={0};一致)

7fyelxc5

7fyelxc51#

C99 §6.7.8 * 初始化 * 说明如下:
要初始化的实体类型应为未知大小的数组或不是可变长度数组类型的对象类型。
所以你的初始化是无效的。
type a[size] * 不是 * VLA的唯一方法是size是一个 * 整型常量表达式 *(参见6.7.5.2节),这里的表达式不是整型常量表达式,所以我们有一个VLA:
如果大小不存在,则数组类型为不完整类型。如果大小为 * 而不是表达式,则数组类型为未指定大小的可变长度数组类型,只能在具有函数原型范围的声明中使用,但此类数组仍为完整类型。如果大小为整数常量表达式,且元素类型具有已知的常量大小,数组类型不是可变长度数组类型;否则,数组类型是可变长度数组类型。
第6.6/6节 * 常量表达式 * 将其定义为:
整型常量表达式应具有整型类型,并且只能具有以下操作数:整型常量、枚举常量、字符常量、结果为整型常量的sizeof表达式,以及作为强制转换的立即数操作数的浮点常量。整型常量表达式中的强制转换运算符只能将算术类型转换为整型类型,但作为sizeof运算符操作数的一部分的情况除外。

ccrfmcuu

ccrfmcuu2#

实际上,对于我的gcc(版本4.4.4),最后一个示例

int main()
{
    const int foo=13;  
    int bar[foo+1]={0}; //wtF?
    return 0;
}

也 * 不 * 编译,正如人们所期望的那样。您可能需要仔细检查您的工具链(以验证您没有在那里的某个地方重新链接现有的.o),然后重试。
如果您发现它真的可以工作,这是我的gcc -v输出,也许您可以检测到配置中的差异,这可能会提供一些线索。

Using built-in specs.
Target: i686-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch=i686 --build=i686-redhat-linux
Thread model: posix
gcc version 4.4.4 20100630 (Red Hat 4.4.4-10) (GCC)
mi7gmzs6

mi7gmzs63#

Matt已经引用了这个标准,应用于整型变量的**const限定符不算作整型常量表达式**。我们可能会问为什么?它看起来和整型常量一样无辜!
这 * 可能 * 是因为const不是绝对的consts。你可以通过指针改变它们的值,编译器所能做的,如果它捕捉到这样的赋值,就是抛出一个警告,但不能真正阻止你改变const的值。
PS:不要相信在线编译器,如ideone.com等。这里有一个愚蠢的runtime error,它抛出一个非常简单的C程序。

相关问题