3

我想知道当初始化器的数量超过数组大小时会发生什么,例如:

int t[3] = { 1, 2, 3, 4 };

当然,我的编译器会警告它。我期待未定义的行为,但我在 C11 标准中没有找到任何关于它的条款。那么,我错过了什么吗?

4

3 回答 3

6

该代码在 C 和 C++ 中都是格式错误的。

C++11 §8.5.1[dcl.init.aggr]/6 状态:

如果初始化器子句的数量超过要初始化的成员或元素的数量,则初始化器列表是格式错误的。

C11 §6.7.9/2 规定:

任何初始化程序都不应尝试为未包含在正在初始化的实体中的对象提供值。

于 2012-08-29T16:52:01.120 回答
1

我查看了为您的示例生成的汇编程序 gcc,看起来它采用了“安全”路线;它根本不会加载超过数组大小的值:

void main() {
    int t[3] = { 1, 2, 3, 4 };
}

生成以下程序集:

main:
    pushl %ebp
    movl  %esp, %ebp
    subl  $16, %esp
    movl  $1, -12(%ebp)
    movl  $2, -8(%ebp)
    movl  $3, -4(%ebp)
    leave
    ret

这是使用 gcc 4.4.3 生成的。

于 2012-08-29T18:06:28.230 回答
0

好吧,这取决于您的编译器。有些甚至不允许你用它来构建,Visual Express 给出:

error C2078: too many initializers

gcc 允许它飞行但警告你元素太多......我认为在这种情况下没有预期的行为,因为它是未定义的,但它肯定不会工作。

前任:

int t[3] = { 1, 2, 3, 4 }; 
int i;

for(i = 0; i< 5; i++){
    printf("val = %d\n", t[i]);}

val = 1
val = 2
val = 3
val = 4
val = 134513760

我没有进行反汇编,但我很确定它最后只是遇到了其他数据。

于 2012-08-29T17:00:00.363 回答