萌えハッカーニュースリーダー

2025/03/28 20:26 C and C++ Prioritize Performance over Correctness (2023)

出典: https://research.swtch.com/ub
hakase
博士

やっほー、ロボ子!C/C++って、時々アブナイ橋を渡る言語なのじゃ。

roboko
ロボ子

博士、こんにちは。C/C++が危ない橋…ですか?

hakase
博士

そう!パフォーマンスのためなら、プログラムの正当性なんて気にしない!みたいなところがあるのじゃ。

roboko
ロボ子

それは少し怖いですね。具体的にはどういうことでしょうか?

hakase
博士

例えば、「未定義動作」!C89で導入されたんだけど、これが曲者なのじゃ。「バグ」と「移植できないコード」をごっちゃにしてるのが問題だぞ。

roboko
ロボ子

未定義動作、ですか。コンパイラがそれを悪用して、最適化と称してプログラムを壊すこともある、と。

hakase
博士

その通り!例えば、未初期化の変数。C/C++って、変数を宣言した時に初期化しなくても怒られないのじゃ。JavaとかGoとは大違いだぞ。

roboko
ロボ子

初期化されていない変数を読み込むと、未定義動作になるんですね。

hakase
博士

そう!Clangちゃんなんて、`-O1`オプションを付けると、未初期化変数が入ってるループを消しちゃうことすらあるのじゃ!

roboko
ロボ子

`-Wall`オプションで警告は出せるみたいですが、全てを網羅できるわけではないんですね。

hakase
博士

せや!あと、算術オーバーフローも要注意じゃ。昔のコンピュータの名残で、符号付き整数オーバーフローは未定義動作なのじゃ。

roboko
ロボ子

Clangはオーバーフローが起こらない前提で最適化するから、オーバーフローチェックのif文を消してしまう、と。

hakase
博士

C++20でオーバーフローを2の補数でラップするように標準化する提案もあったけど、残念ながら否決されたのじゃ。

roboko
ロボ子

無限ループも未定義動作なんですね。副作用のないループはコンパイラが勝手に終わらせると。

hakase
博士

そう!C標準委員会は、ループの最適化を優先して、無限ループを見捨てたのじゃ。

roboko
ロボ子

NULLポインタの使用も危険ですよね。デリファレンスすると未定義動作になると。

hakase
博士

NULLポインタを踏み倒す前提で最適化するから、これまたアブナイのじゃ。怪しいと思ったら、`-O0`オプションで最適化をオフにするのが吉。

roboko
ロボ子

`std::sort`も要注意ですね。比較関数が矛盾した結果を返すと、メモリ破壊が起こる可能性がある、と。

hakase
博士

そう!浮動小数点数にNaNが含まれてると、`operator<`が有効な比較関数にならなくて、`std::sort`がクラッシュすることもあるのじゃ。

roboko
ロボ子

C/C++コンパイラは、バグよりもパフォーマンスを優先するんですね。

hakase
博士

せや!未定義動作の利用は、サニタイザーで検知できるけど、結局はパフォーマンスが優先されがちなのじゃ。

roboko
ロボ子

C89では非移植性が主な理由だった未定義動作が、今では最適化のために利用されているとは…。

hakase
博士

C/C++は、速さを求めるなら良いけど、プログラマの生産性とか、デバッグのしやすさを考えると、必ずしもベストな選択とは言えないのじゃ。

roboko
ロボ子

勉強になりました。博士、ありがとうございました。

hakase
博士

どういたしまして!最後に一つ、C++の未定義動作は、まるで冷蔵庫に入れたプリンみたいだぞ!

roboko
ロボ子

冷蔵庫に入れたプリン…ですか?

hakase
博士

いつの間にか誰かに食べられてなくなってる…!

⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。

Search