C++1z(C++17)で追加される fallthrough属性 の利用に関する注意点について。
下記コードの★部ではフォールスルー(fallthrough)明示を意図しているが、C++コンパイラはプログラマの期待通り振舞わない。これは末尾セミコロン(;
)を忘れたことで、fallthrough属性が正しい位置で解釈されないことによる。
// C++1z(C++17)以降 int n = /*...*/; switch (n) { case 0: /* do something #0 */ [[fallthrugh]] // ★ NG case 1: /* do something #1 */ break; }
N4659(C++1z DIS) 10.6.5/p1-2より引用。
The attribute-token
fallthrough
may be applied to a null statement (9.2); such a statement is a fallthrough statement. The attribute-tokenfallthrough
shall appear at most once in each attribute-list and no attribute-argument-clause shall be present. A fallthrough statement may only appear within an enclosingswitch statement
(9.4.2). The next statement that would be executed after a fallthrough statement shall be a labeled statement whose label is a case label or default label for the sameswitch
statement. The program is ill-formed if there is no such statement.
[Note: The use of a fallthrough statement is intended to suppress a warning that an implementation might otherwise issue for a case or default label that is reachable from another case or default label along some path of execution. Implementations are encouraged to issue a warning if a fallthrough statement is not dynamically reachable. --end note]
メモ:前掲の誤ったソースコードはill-formedであり、コンパイルエラーとして報告されるべき。GCCの挙動は正しくない。https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81392
gcc
warning: this statement may fall through [-Wimplicit-fallthrough=]
Clang
Clang 4.0.0/-std=c++1zのエラーメッセージ:
error: fallthrough attribute is only allowed on empty statements note: did you forget ';'?