gcc で返り値の確認忘れに警告を出す(warn_unused_result)

以前,liblzma のヘッダを眺めているときに気づいたのですが,gcc 3.4 以降では,warn_unused_result という属性を関数に与えておくと,返り値を確認していない場合に警告を出してくれるようです.

わざわざエラーコードを返すような設計にしても,手抜きで確認しなかったり,途中で忘れてしまったりということはよくありますから,重要なところに付けておくことで,バグの発生を防ぐことができるかもしれません.片端から付けておくという荒技も,一つの選択肢としてはあります.ただし,ちょっとしたコードを書いて試したいというときには邪魔です.

属性の指定は,関数の宣言に対しておこないます.関数の定義に対して属性を指定しようとすると gcc に ``error: attributes are not allowed on a function-definition'' と怒られてしまい,コンパイルできません.以下は,ちょっとしたサンプルコードです.

// 関数の宣言にて属性 warn_unused_result を与えます.
int TestFunc() __attribute__((warn_unused_result));

// 関数を定義します.
int TestFunc() { return 0; }

int main()
{
  // 返り値を使っていないと怒られます.
  TestFunc();  // 10 行目です.

  // こちらは返り値を使っているので怒られません.
  int ret = TestFunc();  // 13 行目です.
  return ret;
}

上記のコード(a.cc)を gcc に渡してみると,以下のようになりました.10 行目で呼び出される TestFunc() の返り値が放置されているので,警告が出されています.一方,13 行目に対しては警告がありません.

$ gcc -Wall a.c
a.c: In function ‘main’:
a.c:10: warning: ignoring return value of ‘TestFunc’, declared with attribute warn_unused_result

$ gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

返り値によるエラー処理を忘れがちな自分のために,あるいはエラーコードの見過ごしが致命的なエラーにつながる場合など,使いどころがありそうです.

なお,liblzma のヘッダ lzma.h では,gcc のバージョンをマクロ(__GNUC__, __GNUC_MINOR__)で確認していました.以下のようなノリです.

#if __GNUC__ == 3 && __GNUC_MINOR__ < 4

# 返り値の型が void の関数に付けても何も起きませんでした.