2017-05-03 4 views
0

gcc 4.8.3が不正なテンプレート関数をインライン化するかどうかは疑問です...この問題はデバッグモードでは発生せず、最適化モードでのみ発生します。しかし、これは複雑なコードベースで発生します。単純なテストケースでは問題を再現できません。gccインライン特殊な定義の汎用テンプレート関数

私のコードは、デバッグビルドで、次の

​​

のようなものである最適化されたビルドでは、それはここでプリントアウトしている間、それは、Aをプリントアウト?\ nBと

私は、任意のインライン化汎用テンプレートを使用して推測します特殊な関数定義ではありません。しかし属性((noinline))は役に立ちません。

私のコードに定義されたC++の動作がある場合は誰ですか?この問題を解決する方法は?

+0

私の解決策は、特殊な定義をインライン展開することです:http://stackoverflow.com/questions/4445654/multiple-definition-of-template-specialization-when-using-different-objects –

答えて

2

これは明示的には述べていませんが、実際のコードでは、Aの.hファイルに特殊化を宣言していないと思います。したがって、別のコンパイル単位にA.hが含まれていた場合、コンパイラはWriteNative()の特殊化に気づいていませんでした。専門の宣言を追加する(すなわち、それをインライン化する必要がない)同じファイルに定義を含めることなく、問題を修正する必要があります

class A { 
    public: 
    template<typename T> int WriteNative(const T) { 
     printf("here?\n") 
     return 0; 
    } 

    template<typename D> 
     void doit() { 
     if (WriteNative<double>(1)) { 
      printf("A\n"); 
     } else { 
      printf("B\n"); 
     } 
    } 
}; 
template<> int A::WriteNative(const double); 

次の3つのファイルA.hA.cppを使用して問題を再現することができ、 main.cppA.hが含まれている場合にインライン化が最適化中に発生した、と-O0してコンパイルするとき、何のインライン化が発生していないので、WriteNative()A.cppで定義に対してリンクがあったとき、それは専門の気づかないようA.cppは、専門の定義が含まれているとmain.cpp、 。

編集: これはanswerを参照してください。これは、仕様がこの動作が正しい理由を説明するものです。

14.7.3 [temp.expl.spec]:

テンプレート、メンバーテンプレートまたはクラステンプレートのメンバーは が明示的に特化されていた場合、その専門分野は、前 に宣言されなければならない

6 /そのような使用が発生する のすべての翻訳単位で 暗黙的なインスタンス化が行われるような特殊化の最初の使用。診断は必要ありません。プログラム が明示的な特殊化の定義を提供せず、 暗黙のインスタンス化が行われるか、またはメンバーが仮想メンバー 関数であるような方法で特殊化が使用されるか、診断は必要ありません。 暗黙的なインスタンス化は、明示されていても定義されていない明示的な 特殊化に対しては決して生成されません。

+0

C++で要求されたヘッダーファイルで特殊化を宣言していますか? –

+1

そうではありません。しかし、他のコンパイルユニットは明らかにそれを見ません。これはコンパイル時に何が起こり、リンケージ中に何が起こるかの問題です。 –

+0

@ n.caillou必須ではない場合、最適化はあまりにも積極的です。私は、宣言なしで私の元のコードが定義されていない限り、コンパイラの最適化はコードの動作を変更してはならないと思います。 –

関連する問題