【C言語】
配列領域外参照
配列の添字チェックを先に!

(style) Array index ‘idx’ is used before limits check.

警告:配列添字を範囲チェック前に使った[(style)arrayIndexThenCheck]


■修正前:if(配列[添字]&&範囲チェック)

#include    <stdio.h>
#define MAX 4
char *func(char *ary[],unsigned int idx)
{
    if((ary[idx]!=NULL) && (idx<MAX)){   
        return  ary[idx];
    }
    return  "無色";
}
static char *RGB[MAX]={"赤","緑","青",NULL};
int main(void) {
    printf("%s\n",func(RGB,0));
    printf("%s\n",func(RGB,1));
    printf("%s\n",func(RGB,2));
    printf("%s\n",func(RGB,3));
    printf("%s\n",func(RGB,4));
}

if((ary[idx]!=NULL) && (idx<MAX)){は
第一条件(ary[idx]!=NULL) と
第二条件 (idx<MAX)を
同時に評価するのではなく
左から順番に評価します。

このため(ary[idx]を参照してしまった後で
(idx<MAX)のチェックをしても手遅れです。

配列領域外参照が発生する可能性があり、
これは未定義動作なので
プログラムが異常終了するかもしれません。

筆者の環境下では以下のようになりました。
gcc f1.c -fsanitize=address⇒異常終了する
gcc f1.c -fsanitize=address -O2⇒正常終了する

参考:


■修正後:if(範囲チェック&&配列[添字])

#include    <stdio.h>
#define MAX 4
char *func(char *ary[],unsigned int idx)
{
    if((idx<MAX) && (ary[idx]!=NULL)){   
        return  ary[idx];
    }
    return  "無色";
}
static char *RGB[MAX]={"赤","緑","青",NULL};
int main(void) {
    printf("%s\n",func(RGB,0));
    printf("%s\n",func(RGB,1));
    printf("%s\n",func(RGB,2));
    printf("%s\n",func(RGB,3));
    printf("%s\n",func(RGB,4));
}

if((idx<MAX) && (ary[idx]!=NULL))と
記述すると
第一条件(idx<MAX) が成立しなければ
第二条件(ary[idx]!=NULL)は評価されないので
配列領域外参照は発生しません。