Ubuntu 12.04 および g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 で C++ を使用してプログラミングしています。
テンプレート化された Vector クラスがあります
template <typename type, int length>
class Vector {
// Implementation
};
length
タイプのコンポーネントがありますtype
。
このクラスもテンプレート化された他のクラスで使用します。このクラスは、そのベクトルに使用する要素の数をテンプレート引数 ( dim
) として受け取ります。
この引数は 2 または 3 のいずれかです。if の場合dim == 3
、特別なことをしなければならないので、多かれ少なかれ次のようなことを書きました。
if (dim == 3) {
// do special things here
}
クラスがパラメーター2で呼び出されると、コンパイラーは条件が決して真ではなく、それを変換しないことを認識し、逆にパラメーターが3の場合、コンパイラーは条件が決して偽ではないことを認識し、すべてを変換し、最適化しますif
。
でコンパイルすると-O0
警告は表示されませんが、電源-O3
を入れると、次のarray subscript is above array bounds
ような行を指す警告が表示されます
Vector<pr, dim> v;
v[0] = ...
v[1] = ...
if (dim == 3) v[2] = ...
ここpr
で、パラメータとして指定された型です。
警告が表示される理由がわかりません。なぜなら、 の場合dim == 2
、割り当ては実行されず、3 の場合、割り当ては問題を引き起こさないからです。
私はいつも、テンプレート化は次のように機能すると考えていました。コンパイラはテンプレート コードを取得し、すべてのパラメータを指定されたパラメータに置き換えてから、これを単純なクラスとして扱います。
私の質問は、なぜコンパイラーは、決して起こらないことを知っていることについて私に警告するのですか?
また、最適化を使用してコンパイルすると、なぜ警告のみが表示されるのですか?