読者です 読者をやめる 読者になる 読者になる

warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result

UbuntuGCCとかでこういうのが出る。

解説

「scanfの戻り値を使ってないよ」→つまり、scanfが失敗した場合について考えてないコードを書いてるから気をつけろという警告。

対策1

scanfの戻り値を検査する。
scanfの戻り値は、成功した変数の数、もしくは-1であるので、例えば

if(scanf("%d/%d", &numerator, &denominator) < 2) {
    fprintf(stderr, "error: ill-formed fraction.\n");
    exit(1);
}

このコードでは、"2/3"みたいな分数をスキャンして、その形式でない入力が与えられた場合、エラーを出力して終了する。

対策2

検査の必要がない場合(アルゴリズムとかで、入力が正しいことをいちいち検査するのは逆に邪魔)は、コンパイルオプション「-Wno-unused-result」で抑制する。

g++ -O2 -Wall -Wno-unused-result hello.cpp -o hello

舞台裏

手元の環境では、/usr/include/stdio.hにて

extern int scanf (__const char *__restrict __format, ...) __wur;

と定義されていて、

/usr/include/sys/cdefs.hにて

# define __attribute_warn_unused_result__ \
   __attribute__ ((__warn_unused_result__))

と定義(__GNUC_PREREQ(3,4) のとき)、かつ

#   define __wur __attribute_warn_unused_default__

と定義(__GNUC_PREREQ(3,4) かつ __USE_FORTIFY_LEVEL>0 のとき)されている。

__wurが定義されている関数

例えば、以下のような関数。

  • atof, atoi, strtod, strtof
  • malloc, calloc
  • getenv, system
  • bsearch
  • abs
  • fopen, freopen, popen
  • fscanf, scanf, sscanf, fgets, gets
  • fread, ftell, feof