C/C++ / cast構文にカンマ式を渡して嵌った

さて、失敗談です。

カンマ「,」とコンマは一緒なので、ここではカンマで統一します。

C++にはcast構文があります。

  • static_cast
  • reinterpret_cast
  • const_cast
  • dynamic_cast

これらのキャストは関数ではなく構文なので、カンマ式を渡すことができます。

カンマ式は最後の値を返しますから、予測しないエラーを含んだままコンパイルを通る場合があります。

cast構文をprintfのような可変長引数を受け取る関数や、デフォルト引数をもつ関数に渡すときに注意が必要です。

実験

camma.cc

#include <stdio.h>

inline void hoge(int a_Int, bool a_Option = false) {  // 1 もしくは 2引数をとる
  printf("%d, %d\n", a_Int, a_Option);
}

int main(int argc, const char* argv[]) {
  // カンマ式は最後の値を返す
  printf("static_cast<int>(false)         = %d\n", static_cast<int>(false));
  printf("static_cast<int>(true, false) = %d\n", static_cast<int>(true, false));
  printf("static_cast<int>(false, true) = %d\n", static_cast<int>(false, true));

  printf("\n");
  hoge(static_cast<int>(true), false);          // こう書くつもりで    2引数
  hoge(static_cast<int>(true,  false));         // こう書いてしまった   1引数

  return 0;
}

実行

static_cast<int>(false)       = 0
static_cast<int>(true, false) = 0
static_cast<int>(false, true) = 1

1, 0
0, 0

まとめ

gccやclangなら、-Wall や -Wunused-parameterをつけることで、警告してくれます。 警告を見落とさないように注意しないと嵌ります。

# LC_ALL=C gcc ...
./camma.cc:24:33: warning: left operand of comma operator has no effect [-Wunused-value]
   hoge(static_cast(false,  true));

# LC_ALL=C clang ...
./camma.cc:24:25: warning: expression result unused [-Wunused-value]
  hoge(static_cast(false,  true));

やらかした話でございました。

paiza.ioを貼ってみよう

ブラウザで実行できるとかすごいなぁ

0 件のコメント:

コメントを投稿