C++標準ライブラリにおけるnodiscard属性の使われ方についてメモ。
2024-05-21追記:2024年3月会合でP3201R1 LEWGポリシーが採択*1され、C++標準ライブラリではnodiscard属性を用いないと決定した。あくまでライブラリ仕様規定から削除されるだけであり、各C++処理系の判断でnodiscard属性は利用されうる。C++23現在はnodiscard指定される関数からも削除される可能性が高い。
2024-07-05追記:2024年6月会合で提案文書P2422R1が採択され、C++2c(C++26)標準ライブラリの仕様としては全ての関数からnodiscard属性が削除される。
関数戻り値の誤った破棄を警告する目的でC++17言語仕様に導入された。標準ライブラリではC++2a(C++20)からの利用となる。2018年8月現在、下記関数がnodiscard属性付与対象となっている。
operator new,operator new[]- 標準アロケータの
allocateメンバ関数 - 標準コンテナ(文字列系含む)の
emptyメンバ関数 std::async関数(→id:yohhoy:20120317, id:yohhoy:20140315)std::launder関数(→id:yohhoy:20170817)
C++標準ライブラリ中でのnodiscard利用に関する提案文書P0600R1では、下記の基本ルールを定めている。
- 属性付与すべきケース:
- 戻り値の未使用が常に “重大なミス(huge mistake)” となるケースに付与する。メモリ確保系の関数。
- 戻り値の未使用がトラブルの元となり、かつ容易に起こりうるケースに付与する。
empty,async,lanuderなどはこちら。
- 属性付与すべきでないケース:
- 一部の入力値に対しては戻り値未使用が合理的であるケースには付与しない。
reallocへのサイズ0指定など(free相当の動作)。 - 戻り値の未使用は無意味だが実害が無く、通常は失敗しないケースには付与しない。printf系, コンテナアダプタの
top, スマートポインタのreleaseなど。 - Cライブラリ互換APIには付与しない。
mallocは対象外。
- 一部の入力値に対しては戻り値未使用が合理的であるケースには付与しない。
関連URL
- (PDF)P0600R1 [[nodiscard]] in the Library, Rev1
- cppreference nodiscard, cpprefjp [[nodiscard]]属性
- Trip report: Winter ISO C++ standards meeting