ローカルな文字列テーブル

関数内で使うローカルな文字列テーブル(配列)の定義には注意が必要です。

1月~12月までの月を数値で渡すと、英語の文字列を取得できる関数monthToEnglishを作ってみましょう。

例.第一引数に5を渡すとMayという文字列が第二引数のバッファに格納される

無事、完成しました。

有効範囲のエラー処理など細かい部分は端折ってますが適切な値を渡す限りは要件に見合った挙動をします。

さてこの関数ですが、大いなる無駄処理が走る可能性があります。

最適化を有効にした上で、アセンブラを見てみましょう。

41行目~に注目です。

MONTH_ENGLISH_TABLEはこの関数が呼び出される度にスタック上にコピーされます。ちなみにconst を constexprに変えても出力結果は同じです。

スタック上に値を生成したいという目的が無いのならば、このコードはこの関数が呼ばれる度にただただ不要な処理を走らせることになるのであまりよろしくありません。

例えばテクスチャ名のリスト、モーション名のリスト、気軽にローカルで定義することは良くあるかと思います。

そういう時に、gcc 4.9.2 で -O3ですら、前述のような(プログラマの意図に対して)無駄な処理が走ることは覚えておく価値があると思います。

この問題は定義にstaticを付けることで簡単に回避できます。

この場合のアセンブラコードを見てみましょう。

見違えるほどスッキリしました。

このように、関数ローカルな場所に文字列テーブルを作る時は呼吸をするようにstaticを付けるというプラクティスは悪くありません。

まとめ

  1. ローカルな文字列テーブルの定義は無駄なコストが生じる可能性がある
  2. ローカルな文字列テーブルにはstaticをつけよう
Pocket