(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)は評価されないので
配列領域外参照は発生しません。