アカウント名:
パスワード:
`key_data_->label().empty()`に副作用がないなら条件付きか否かで変わらなくない?と思ったが、C++だと&はビット演算で両方trueでもfalseになることがあるのか。&&と&は条件付きかだけじゃなく評価の仕方が違うのね。C#で両辺boolなら無視できるパフォーマンス上の問題でしかないからピンとこなかったわ。
確かに&はビット演算ですが今回の原因はビット演算だからではありません。&&はショートサーキット評価で左の値がfalseのときは右側が実行されませんが、&では左の値に関わらず右が実行されてしまいます。key_data_の定義はbase::Optional<KeyData> key_data_;となっており、base::Optionalというのはstd::optionalのChromium版の実装です。左側では key_data_.has_value() と値が存在しているかどうかをチェックした上で、右側で key_data_->label() とデータにアクセスしていますが、has_value()がfalseならアクセスすべきデータが存在しないのでundefined behaviourとなります。多分nullptrへのアクセスでクラッシュしますね。
あーnullアクセスか。これなら普通だな。勘違いしてた。メンバアクセスがアロー演算子 [github.io]と(若干良く分かってない)。if(!(key_data_ is null) && !key_data_.label().empty()){ return key_data_.label(); }相当か。
この辺null条件演算子が出来てからだいぶ楽になったなぁ。
unique_ptrとかならnullアクセスになるだろうけど、今回はOptionalだからnullアクセスにはならない。未初期化なデータ領域へのアクセスでのUB。
元コメと同じことを言ってますよ?
> アクセスすべきデータが存在しないのでundefined behaviourとなります。多分nullptrへのアクセスでクラッシュしますね。
UB(undefined behavior)であり、gcc/clang系のreleaseビルドなら大抵 nullptr でしょう。だから”多分”と言ってる。
C/C++ってJavaScriptとかの派生言語とは違って文中の評価順序は一部不定で頼るべからずな印象なのだけど、論理演算における短絡評価だけは明確な仕様なんですね。# 仕様と言いつつオーバーロードすると不定になるらしいけど
C/C++の不定・未定義の闇、怖い……
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
私はプログラマです。1040 formに私の職業としてそう書いています -- Ken Thompson
なんで? (スコア:3, 参考になる)
`key_data_->label().empty()`に副作用がないなら条件付きか否かで変わらなくない?
と思ったが、C++だと&はビット演算で両方trueでもfalseになることがあるのか。
&&と&は条件付きかだけじゃなく評価の仕方が違うのね。
C#で両辺boolなら無視できるパフォーマンス上の問題でしかないからピンとこなかったわ。
Re:なんで? (スコア:0)
確かに&はビット演算ですが今回の原因はビット演算だからではありません。
&&はショートサーキット評価で左の値がfalseのときは右側が実行されませんが、&では左の値に関わらず右が実行されてしまいます。
key_data_の定義は
base::Optional<KeyData> key_data_;
となっており、base::Optionalというのはstd::optionalのChromium版の実装です。
左側では key_data_.has_value() と値が存在しているかどうかをチェックした上で、右側で key_data_->label() とデータにアクセスしていますが、has_value()がfalseならアクセスすべきデータが存在しないのでundefined behaviourとなります。多分nullptrへのアクセスでクラッシュしますね。
Re: (スコア:0)
あーnullアクセスか。これなら普通だな。勘違いしてた。
メンバアクセスがアロー演算子 [github.io]と(若干良く分かってない)。
if(!(key_data_ is null) && !key_data_.label().empty()){ return key_data_.label(); }
相当か。
この辺null条件演算子が出来てからだいぶ楽になったなぁ。
Re: (スコア:0)
unique_ptrとかならnullアクセスになるだろうけど、今回はOptionalだからnullアクセスにはならない。
未初期化なデータ領域へのアクセスでのUB。
Re: (スコア:0)
元コメと同じことを言ってますよ?
> アクセスすべきデータが存在しないのでundefined behaviourとなります。多分nullptrへのアクセスでクラッシュしますね。
UB(undefined behavior)であり、gcc/clang系のreleaseビルドなら大抵 nullptr でしょう。だから”多分”と言ってる。
Re: (スコア:0)
C/C++ってJavaScriptとかの派生言語とは違って文中の評価順序は一部不定で頼るべからずな印象なのだけど、
論理演算における短絡評価だけは明確な仕様なんですね。
# 仕様と言いつつオーバーロードすると不定になるらしいけど
C/C++の不定・未定義の闇、怖い……