2016-07-12 2 views
12

VS2015アップデート2の場合、再現性の低いテストケースは次のとおりです。私たちは「警告レベル4」を構築しようとしていました。警告を致命的なエラーとして扱い、警告に気付く可能性を高めました。私はコミュニティの誰かがすでにこの問題にぶつかり、合理的な回避策を見つけたことを願っています。コンパイラのバグのために到達不能なコードの警告を回避するには?

他の誰も同等の問題が発生していない場合は、ローカライズされすぎる可能性があるので、根本的な問題は「悪いコンパイラの警告を回避するためにコードベースを悪くしなければならないか」、 "バグレポートを失うコンパイラベンダーにバグを報告する方法は?"

#ifdef _WIN32 
#pragma warning(push) 
#pragma warning(disable : 4702) // As suggested by comments 
#endif 
template <class Type> 
void func (Type t) 
{ 
    t.func(); 
    t.func(); 
} 
#ifdef _WIN32 
#pragma warning(pop) 
#endif 

struct NoThrow 
{ 
    void func() {} 
}; 

struct Throws 
{ 
    void func() {throw 1;} 
}; 

int main() 
{ 
    NoThrow nt; 
    func (nt); 

    Throws t; 
    func (t); 
} 

これにより、到達不能なコードの警告が表示されます。テンプレート化された関数はそれ自体が妥当に見えますが、ある特定のインスタンス化では、コンパイラは2番目のt.func()が死んでいると判断できるため、到達不能なコードについて警告します。

これは、VS2015の実装上の問題がかなり明確になっているようだから、バグレポートhereを開いた。

我々は残念ながら(この警告を発し)コンパイラのバックエンドは、単一のテンプレート関数のインスタンスとしてテンプレート関数のインスタンス化の本当の概念を持っていない、マイクロソフトから

をいくつかの指導を受けました。彼らはお互いに(飾られた)名前を比較するのに悩まされた場合、非常に似通った見た目の名前を持つただの機能です。それは決してしません。だから、ここでは、到達不能なコードを持つ関数の1つが警告されており、到達できないコードがない別の関数があります。この「クロスファンクション警告」のコンセプトは、さまざまなテンプレートのインスタンシエーション間でデータを収集して比較し、純粋なLTCGバイナリでは非常に難しく、それ以外の場合は不可能な場合にのみ警告します。

ヘッダーfoo.hにテンプレートFooがあるとします。 a.cppがそれを含み、到達不能なコードでFooを作成し、b.cppがそれを含み、到達不能コードなしでFooを作成すると仮定します。 a.cpp Fooは到達不能コードなしで存在するため、Fooは到達不能コードを警告してはいけません。しかし、Fooは異なるファイルで、別のプロセスで、cl.exeの別の呼び出しで、そして最も不都合に将来コンパイルされます。明らかに、コンパイラは未だ生まれていないプロセスに未来に到達し、警告すべきかどうかを計算するために必要な情報を引き出す能力を持っていません。

私たちがここで持っている唯一の実用的なオプションは、到達可能なコードの警告をすべて一括してオフにすることです。完了(それはネット不良です)。警告には誤認があります。私は他のオプションについて考えるつもりで、行番号/ファイルの事を調べます。

上記のリンクは利用できないかもしれませんが、インターネットは、キャッシュが付属して、あなたはコピーhereを参照するか、または2744730、誤っ到達不能コード・警告・イン・テンプレート・インスタンス化を使用して、独自のを見つけることができます。

基本的なテンプレートのインスタンス化モデルは、関数のコピーをスタンプし、他のものと同じ警告分析を受けると仮定すると、デッドコード警告を回避するにはどうすればよいでしょうか?私は現在、影響を受けているダースまたはそれに近いテンプレートへのタグのディスパッチを追加するか、警告をグローバルにオフに切り替えるかの間に悩まされています。

編集:直接リンク私は、これはそれによっては迷惑な正しい行動であることを言うだろう、再び

+3

['#pragma warning'](https://msdn.microsoft.com/en-us/library/2c8f766e.aspx)が1つの方法かもしれません。 –

+2

私は、コンパイラのバージョンを確認し、可能な場合は警告が無効にされている理由のメンテナンスプログラマやアイデアを与えるためにバグレポートにリンクコメントがなければならないことを付加した二イゴールの提案よ。 (可能であれば、テンプレート展開の最後に警告それを再度有効 - (とはいえ、これは、テンプレートの展開では動作しない場合があります)。) –

+3

正直なところ、Microsoftの声明は、私には意味があります。彼らは積極的にあなたを助けるための警告を提供しています。テンプレートは、インスタンス化の正確な警告を提供できない領域です。それが気になるなら、これらの警告を「プラグマ」することができます。しかし、この例では私がキャッチし、あなただけのための警告をクリアしないと再スローが、それはあなたのコード内で何が起こっているかを明らかにするだろうと思います。 –

答えて

1

ライブのようです。実施者は

template <class Type> 
void func (Type t) 
{ 
    t.func(); 
    t.func(); 
} 

となります。また、無効または有効なコードを生成するすべてのTypeが存在しない場合は、コンパイラが並べ替えることはできません。したがって、Typeが指定されるのを待って、コードがその固定タイプで入力されたかのようにほとんど続きます。

関連する問題