warning: ‘%s’ directive argument is null
[-Wformat-overflow=]
■Windows系で許容される?がLinux系ではNG
#include <stdio.h>
int main(void){
printf("1:%d\n", 0);
printf("2:%c\n", '\0');
printf("3:%s\n", "");
printf("4:%s\n", NULL);//★ 未定義動作
printf("%s\n", NULL);//★ 未定義動作
fflush(stdout);
}
Windows系のコンパイラでは書式%sにNULLポインタが渡ると
“(null)”と表示されるそうですが、
Linux系(gcc,clang)では
コンパイラと最適化レベルで結果が異なります。
”(null)”と表示されたり
Segmentation faultと表示して異常終了したりします。
●筆者環境下の実行結果
./a.out
1:0
2:
3:
4:(null)
Segmentation fault (コアダンプ)
■戻り値をチェックしないでNULLとなる例
#include <string.h>
#include <stdio.h>
int main(void){
const char *cp = "abc,def,ghi";
printf("%s\n",cp);
cp = strchr(cp,',');
printf("%s\n",cp);
fflush(stdout);
cp = strchr(cp+1,',');
printf("%s\n",cp);
fflush(stdout);
cp = strchr(cp+1,',');
printf("%s\n",cp);
fflush(stdout);
}
書式%sにNULLポインタを渡すのはC言語規格外の未定義動作なので
職業プログラマはきちんとstrchr()の返却値をチェックして
書式%sにNULLポインタが渡らないようにチェックしましょう。
●筆者環境下の実行結果
./a.out
abc,def,ghi
,def,ghi
,ghi
Segmentation fault (コアダンプ)
参考:
FIO47-C. 書式指定文字列を正しく使う
https://www.jpcert.or.jp/sc-rules/c-fio47-c.html