noreturn属性の使い道

ずいぶん前にアドホック会議で議論して以来、とくに書いてなかった気がするので、noreturn属性の使い道について書きます。

C++11で属性構文が導入され、それと同時に[[noreturn]][[carries_dependency]]という2つの属性が標準で入りました。このうち[[noreturn]]は、「その関数が決して返らないことをコンパイラに伝える」という意味の属性になります。

このnoreturn属性は、以下のようなプログラムでの、警告消しのためにあります。

#include <stdexcept>

[[noreturn]] void report_error()
{
    throw std::runtime_error("error");
}

int f(int x)
{
    if (x > 0) {
        return x;
    }
    report_error();
}

int main()
{
    f(1);
}

このプログラムでの関数f()には、例外を投げるパスと例外を投げないパスが存在します。

例外を投げるパスの方に、直にthrow std::runtime_error("error");と書かれていればコンパイラは警告を出力しませんが、例外を投げる処理がラップされているとコンパイラは「関数f()には返らないパスが存在します」という警告を出力します。

このような場合に警告を黙らせるために、noreturn属性があります。例外を投げたり、abort()exit()でプログラムを終了させたりする関数にこれを付けます。

C++の規格には「警告」という概念がないので、規格書を見ても使い道はわかりません。

参照

修正履歴

  • コメント欄での指摘を受け、例のf()関数を、非void型を返すよう修正(2014/01/14 17:41)