アカウント名:
パスワード:
実装なのか想像するスレ
昨日twitter上でいろいろと話していました。えーっと…1. memcmp は、通常、差異がある場合は先頭バイトの差を返す(-255~255)2. ところが SIMD 命令などで memcmp が最適化された場合、char の範囲外(int範囲とか)になってしまう可能性がある。3. その戻り値を char にキャストしているため、場合によっては下位 8bit が 0 になって、一致してしまう。てなことらしい。たぶん。
先頭バイト値の差だとしても、既にchar型の範囲外だね。char型は-128〜127
というより、関数の戻り値がintなのにcharにキャストしてしまっている時点で、ただのバグだね。SSE最適化とかは本質的には関係ないな。
自己レス失礼。理解した。-255〜255だと、元が0でなきゃchar型にキャストしても0にならない範囲内なのね。これは確かにうっかりしそうだ。
それでも縮小キャストしてる時点で終わってますが。
しかもその理由が「コンパイラが警告を出すから」だったりするし。
ナローキャストしないと警告を出すなんて!?と思ったが、こういうことだな。
char型を返す関数内でmemcpy関数の戻り値を引き回した。intからcharへの暗黙のナローキャストが発生しているので、コンパイラが警告を出した。明示的にキャストを追加したら警告が出なくなった。(明示的なキャストは「わかっててやってる」はずのものなので)幸せになったつもりが、不幸せになっていた。
"Because of incorrect casting" と書いてありますね。
memcmp の戻り値を char に変換した上で 0 と比較してるんじゃないでしょうか。memcmp の戻り値は、一致の場合0、違う場合は正または負の整数ですが、0じゃない整数を char に変換すると 1/256 の確率で 0 になって一致したことになると。この場合、戻り値の整数値に 1 または -1 しか使わないような実装の memcmp なら問題は生じないので、実装によっては大丈夫という理由も説明できます。
未初期化変数返してるんじゃないかな。一致した時だけ0を入れてて、そうでないときは何もしてないとか。
typedef char BOOL;とかやってるとはまりそうですね。
SSE最適化版のみってことだからマルチバイトで比較して memcmp から結果を返す前に char にキャストしてんじゃないかな。
わざわざ、なんでキャスト?っておもってみたらcharを返す関数でmemcmpの戻り値そのままreturnで返してるんですね。こんなキャストなら俺もミスするかも
それキャストじゃなくて暗黙の型変換じゃん。型変換を何でもかんでもキャストと呼ぶバカは爆発しろ。ってMySQLの開発者が言ってんのか。深刻すぎる
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
私は悩みをリストアップし始めたが、そのあまりの長さにいやけがさし、何も考えないことにした。-- Robert C. Pike
どういう (スコア:0)
実装なのか想像するスレ
Re:どういう (スコア:5, 参考になる)
昨日twitter上でいろいろと話していました。えーっと…
1. memcmp は、通常、差異がある場合は先頭バイトの差を返す(-255~255)
2. ところが SIMD 命令などで memcmp が最適化された場合、char の範囲外(int範囲とか)になってしまう可能性がある。
3. その戻り値を char にキャストしているため、場合によっては下位 8bit が 0 になって、一致してしまう。
てなことらしい。たぶん。
Re:どういう (スコア:1)
先頭バイト値の差だとしても、既にchar型の範囲外だね。char型は-128〜127
というより、関数の戻り値がintなのにcharにキャストしてしまっている時点で、ただのバグだね。
SSE最適化とかは本質的には関係ないな。
Re:どういう (スコア:1)
自己レス失礼。
理解した。
-255〜255だと、元が0でなきゃchar型にキャストしても0にならない範囲内なのね。
これは確かにうっかりしそうだ。
それでも縮小キャストしてる時点で終わってますが。
Re: (スコア:0)
しかもその理由が「コンパイラが警告を出すから」だったりするし。
Re: (スコア:0)
ナローキャストしないと警告を出すなんて!?
と思ったが、こういうことだな。
char型を返す関数内でmemcpy関数の戻り値を引き回した。
intからcharへの暗黙のナローキャストが発生しているので、コンパイラが警告を出した。
明示的にキャストを追加したら警告が出なくなった。(明示的なキャストは「わかっててやってる」はずのものなので)
幸せになったつもりが、不幸せになっていた。
Re:どういう (スコア:2, 参考になる)
"Because of incorrect casting" と書いてありますね。
memcmp の戻り値を char に変換した上で 0 と比較してるんじゃないでしょうか。memcmp の戻り値は、一致の場合0、違う場合は正または負の整数ですが、0じゃない整数を char に変換すると 1/256 の確率で 0 になって一致したことになると。この場合、戻り値の整数値に 1 または -1 しか使わないような実装の memcmp なら問題は生じないので、実装によっては大丈夫という理由も説明できます。
Re:どういう (スコア:1)
未初期化変数返してるんじゃないかな。
一致した時だけ0を入れてて、そうでないときは何もしてないとか。
スルースキル:Lv2
Keep It Simple, Stupid!
Re: (スコア:0)
typedef char BOOL;
とかやってるとはまりそうですね。
Re: (スコア:0)
SSE最適化版のみってことだからマルチバイトで比較して memcmp から結果を返す前に char にキャストしてんじゃないかな。
Re: (スコア:0)
わざわざ、なんでキャスト?っておもってみたら
charを返す関数でmemcmpの戻り値そのままreturnで返してるんですね。
こんなキャストなら俺もミスするかも
Re: (スコア:0)
それキャストじゃなくて暗黙の型変換じゃん。型変換を何でもかんでもキャストと呼ぶバカは爆発しろ。ってMySQLの開発者が言ってんのか。深刻すぎる