【C言語】
for文回り過ぎ?
(バッファオーバーラン)

warning: iteration 1024 invokes undefined behavior

警告:ループカウンタ 1024 で未定義動作
[-Waggressive-loop-optimizations]


■失敗例1.<と<=を間違える

static int  ary[1024];
int main(void){
    for(int i = 0 ; i <= 1024 ;i++){//★NG
        ary[i] = 0 ;
    }
}

●修正例1.<に変更する

static int  ary[1024];
int main(void){
    for(int i = 0 ; i < 1024 ;i++){
        ary[i] = 0 ;
    }
}

■失敗例2.要素数とサイズを間違える

#include <stdint.h>
static char aryC[1024];
static int  aryI[1024];
int main(void){
    //たまたま上手くいく例
    for(uint32_t i = 0 ; i < sizeof(aryC) ;i++){
        aryC[i] = 0 ;
    }
    //配列の要素数とサイズは違う
    for(uint32_t i = 0 ; i < sizeof(aryI) ;i++){//★NG
        aryI[i] = 0 ;
    }
}

要素数はサイズではありません。
sizeof(ary) != 1024
sizeof(ary) == sizeof(int)*1024 
です。

このコードではLP64モードの場合、4096回転するので
配列の領域外破壊が発生します。

●修正例2.

#include <stdint.h>
static char aryC[1024];
static int  aryI[1024];
int main(void){
    const uint32_t maxC = sizeof(aryC)/sizeof(aryC[0]);
    for(uint32_t i = 0 ; i < maxC ;i++){
        aryC[i] = 0 ;
    }
    
    const uint32_t maxI = sizeof(aryI)/sizeof(aryI[0]);
    for(uint32_t i = 0 ; i < maxI ;i++){
        aryI[i] = 0 ;
    }
}

配列の要素数を求める定石 sizeof(配列)/sizeof(配列[0])を使います。

■失敗例3.添え字の掛け算で桁あふれ

//gcc loop.c -fsanitize=address,undefine
#include    <stdio.h>
#include    <stdint.h>
int main(void){
    for (int i = 0; i < 4; i++){
        int64_t j = i * 0x40000000 ;
        printf("%lx\n",j);
    }
}

i * 0x40000000の計算式でiが3の時、
INT_MAXで収まらないので桁溢れしてしまいます。

●修正例3.接尾子Lを使ってlong型演算を行う

//gcc loop.c -fsanitize=address,undefine
#include    <stdio.h>
#include    <stdint.h>
int main(void){
    for (int i = 0; i < 4; i++){
        int64_t j = i * 0x40000000L ;
        printf("%lx\n",j);
    }
}