プログラミング言語Cの次期仕様C2x(C23)では 属性(attribute) 構文が標準化される。属性構文を先行導入したC++言語とほぼ等価であり、連続するブラケット[[
/]]
を用いる。*1
// C2x [[nodiscard]] int f(); void g([[maybe_unsed]] int a) { [[maybe_unused] int x; /* ... */ } struct [[deprecated("old ver.")]] S { /*...*/ }; int n = f(); switch (n) { case 0: case 1: f(); [[fallthrough]]; default; g(n); break; }
属性指定を行える箇所:
- 構造体(
struct
)/共用体(union
)の型宣言 - 列挙型(
enum
)の型宣言 - 列挙子(enumerator)の定義
- 変数/関数仮引数の宣言
- 関数の宣言/定義
- 任意の文(statement)
2020年2月時点のC2xドラフト*2で追加される属性は下記4種類
2022-08-07追記:Feature Freeze版とされる2022年8月時点のC2xドラフト*3で追加される属性は下記7種類*4:
nodiscard
(→(PDF) N2267)- 2021-02-28追記:(PDF) N2448 nodiscard("should have a reason") も採択済み。
maybe_unused
(→(PDF) N2270)deprecated
,deprecated("string-literal")
(→(PDF) N2334)fallthrough
(→(PDF) N2408)- 2022-07-26追記:
noreturn
,_Noreturn
(→(PDF) N2764)- C11で導入された<stdnoreturn.h>標準ヘッダ、
_Noreturn
関数指定子(function specifier)、およびC2xの_Noreturn
属性ともに廃止予定(obsolescent feature)とされる。
- C11で導入された<stdnoreturn.h>標準ヘッダ、
- 2022-08-07追記:
reproducible
,unsequenced
(→N2956)(→id:yohhoy:20220909)
C++属性構文との共通点/差分:
- C++同様に、処理系定義(implementation-defined)の属性を許容する。未知の属性は無視される。
- C++同様に、処理系定義の属性用に名前空間(相当)を指定できる。*5
- C2xの属性
attr
は前後にアンダースコア2つを追加した__attr__
と同義。例:[[nodiscard]]
と[[__nodiscard__]]
は同じ属性を表す。 - 2021-07-17追記:属性の重複指定を許容する(→(PDF) N2557)。C++2b(C++23)側もWG21 N2156R1を採択予定。
- 2022-08-07追記:
__has_c_attribute
機能テストマクロ(→(PDF) N2553)
関連URL
- (PDF) N2335 Attributes in C
- cpprefjp 属性構文, cppreference attribute specifier sequence
*1:C2x/C++いずれの言語仕様でも新規トークン [[ や ]] は導入せず、“ブラケット [ または ] が2トークン連続(空白を挟んでもよい)” を属性の開始/終了として扱う。
*2:http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2478.pdf
*3:https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3047.pdf
*4:いずれもプログラム意味論には影響を与えず、標準属性を無視してもプログラム動作は変化しない。それぞれC2x標準属性のサポートは処理系定義のオプションとされるが、各処理系は標準属性を実装することが推奨(recommended)される。
*5:C言語には名前空間(namespace)が存在しないため、属性構文でのみ利用する専用の構文要素 attribute-prefix とコロン2つからなる新しいトークンを導入している。┐(´-`)┌
*6:https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0941r2.html