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 に答える