C++17を知るその3~教育委員会~

3回目の今回は属性。
属性(attributes)は、ソースコードに対して追加の情報をコンパイラに伝えるための構文。
C++11で[[noreturn]],[[carries_dependency]]が追加されていました。

その属性でC++17において追加されていたものがありますので見ていきます。

・[[fallthrough]]属性

switch-case文でよくある

こんな感じのコード。
caseの1と2で同じ処理を行いたい場合こんな感じで記述することがありますが賢いコンパイラーさんは「おい、処理が突き抜けているぞ!」と(warning: this statement may fall through)警告を出してくれます。
そこで警告をうざいと感じて警告を出さないようにしていまうと本当に気づきたいときに出ない、というオチになったり。。

ということでこの[[fallthrough]]は「これはあえてそうしているのだ!警告は無用だ」と教えてあげることができると。

上記のようにcase2のパターンで[[fallthrough]];を書いてあげると警告は出ない、case1の場合だとそもそも[[fallthrough]];はいらない
C#なんかフォールスルー自体禁止している言語もあるので使わないのがベストか(case1,case2の連続するパターンの場合はC#でもOK)

・[[maybe_unused]]属性
使用しない可能性のある変数に対する警告を抑制するためのもの
そんなもの何に使うんだとと思うがassert使用時とかか。

たとえば

上記の場合boolfunc関数の引数aをassertに指定しているが#define NDEBUGが定義されているので無効となります。なのでaは未使用として

てな感じででちゃう。

そこで

てやると警告はでなくなる。

・[[nodiscard]]属性
関数の戻り値を破棄してはダメ、破棄した場合は警告を発生させる

ある関数で処理が行われたとき、エラーだった場合falseなり値を返すがその値を呼び出し側が使用していない。

上記のようなコードがあった場合(もう少しましなものがよかったが)このコードでは警告は発生しない。
しかし

とすれば

という感じで警告を発してくれる。
静的解析ツールとかでいい感じに警告は発してくれるだろうが警告をだせるようになった。

・名前空間と列挙子への属性付加を許可

こんな感じでnamespaceやenumにも属性が書けるようになった。

・属性の名前空間指定に繰り返しをなくす
なんのこっちゃと思いましたが

これが

こうなる

ただしusing指定できるのは一つだけのよう。あとusingと名前空間の指定は混在できないとのこと

まあ混在できるとややこしいからいいか。

・不明な属性を無視する

GCC/Clangではgnu::deprecated属性が使用されそれ以外では無視される。

これによっていちいち#ifdefとかでコンパイラごとに考慮するようなことは必要がなくなった。

というわけでC++17で変わった使わないようで結構使うかもしれない属性関連でした。

About the author

naito06

C++やったり、PythonやったりPHPだったり。

Add Comment

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

By naito06

最近の投稿

アーカイブ

カテゴリー

タグクラウド

コーポレートサイト

メタ情報