0

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 の場合、割り当ては問題を引き起こさないからです。

私はいつも、テンプレート化は次のように機能すると考えていました。コンパイラはテンプレート コードを取得し、すべてのパラメータを指定されたパラメータに置き換えてから、これを単純なクラスとして扱います。

私の質問は、なぜコンパイラーは、決して起こらないことを知っていることについて私に警告するのですか?

また、最適化を使用してコンパイルすると、なぜ警告のみが表示されるのですか?

4

1 に答える 1

2

ifコンパイラは、条件が満たされない場合でもコードをコンパイルし、警告を出します。

警告が実際に実行されないようにするため、警告を無視するかif、パラメータが 3 の場合に関数/クラスを特殊化/SFINAE して余分な処理を行うことができます。

または、取得するまで 5 年ほど待ちますstatic_if

于 2012-12-31T17:23:13.297 に答える