見出し画像

C/C++の策定と最適化の問題

ちょっと気になったことがあったので実証する前に内容だけ書こうと思います。


1. 最近のコンパイラは過剰なほど賢い?

というのも、最適化によるコードの変更が凄すぎるんですよね。今や SSEとか当たり前になってきてますし。

そんなコンパイラも人間が意図してないコードに置き換えてしまうこともあります。

例えばよく知られてるのは memset とかでしょうか。最適化することで、コードが消されちゃうことがありますから困ったものです。

void main()
{    char *p = malloc(128);
    
    // 適当な処理free(p);
​
​    // 見られないようにクリアするmemset( p, 0, _msize(p) );
}

こんな感じでしょうか。

コンパイラから見ると memset に渡している p はそれ以降使われていないので無駄な処理と判断します。
じゃあ、いらないから消しちゃおう!ってコンパイラはそそくさとなかったことにしてしまいます。

人間からするとセキュリティのためにメモリをゼロクリアしたかったのですが💦

コンパイラの設計にもよりますが VCはやります。/O2でもやります。


2. 関数の策定

memmovememcpy の違いってわかりますか?

どちらの関数も A から B にデータをコピーするものですよね。
ところが、中身は違うんです。

memmove はデータが破壊されないように A と B の位置関係から後ろからコピーを行うなどして破壊されないように心がけています。でもその分処理時間が増えます。

一方 memcpy は速度優先でデータの破壊の可能性を考えずどんどんコピーしていきます。

両方とも結果は同じになるはずですが、場合によってはメモリ破壊を起こすこともあるわけです。

C++11にいたっては std::swap の実装が変わってたりと影響はないと思いますが、いろいろ変わっています。

また、古くからある register キーワードは C++11では非推奨となり、C++14ではなくなります。


3. まとめ

まとめって程じゃないですけど、言語仕様を把握するために Draftは常にチェックしとこうぜ!って話です。

上での問題もセキュリティに対応した関数ができたり、volatile で対応したりと方法はあります。

この先、C++14,17,20と待ち構えているので変化に追いつけるように準備しておきましょう。

いきなりテンプレートテンプレートパラメータって言われてわかりますか?
using でできることが増えたの知ってますか?

おそらくこの先 C++は他の言語の影響と boost のせいで変態言語になっていくかもしれないので取り残されないようにしましょう〜。

時間があればアセンブラを見ながら実証してみたいですね。



悉く書を信ずれば則ち書無きに如かず