「インライン関数ではありません」って何が悪いの!?(泣)
「Visual C++ 6.0」で何かバグっぽい…。
インラインなんか無いのに「インライン関数ではありません」って
警告が山のよう出る!
一体何が悪いのさ!
って言うのも警告は、隠れたバグを発見するのに有効なので
「警告レベル」を「レベル4」にしてあるのだが…
デバッグモードでは出ない警告が、リリースモードで山のように出る!(泣)
って訳で…
一体何がぁ!
悪いのさぁ~!
悪いのさぁ~!
悪いのさぁ~!
…
…泣きながら調べてみた…。
どうやらテンプレートが悪さをしているようだ。
テンプレートを使用すると使っている所を
全てをインライン展開しようとしているみたいだ…。
同じ物は、作らないっんじゃ無かったっけ?
取り合えず警告を黙らせる方法は、分かった!
「#pragma warning(disable:4710)」
を使えば黙ってくれる!
簡単なモデルで再現をしてみる。
#include<windows.h>
//#pragma warning(disable:4710)
#define DA(p) {if(p!=NULL){delete[] p;p=NULL;}}
#define EE(r) {if(r){return FALSE;}}
template<typename TYPE>
class TC{public:
TC(){d=NULL;}
~TC(){DA(d);}
BOOL C(int n){EE((d=new TYPE[n])==NULL);return TRUE;}
TYPE *d;
};
#else
template<typename TYPE>
class TC{public:
TC(){d=NULL;}
~TC(){if(d==NULL){if(d!=NULL)delete[]d;d=NULL;}}
BOOL C(int n){if((d=new TYPE[n])==NULL)return FALSE;return TRUE;}
TYPE *d;
};
#endif
template class TC<int>;
class CA{public:
TC<int>i0;
TC<int>i1;
TC<int>i2;
TC<int>i3;
TC<int>i4;
#if 1
#if 1
TC<int>i5;
TC<int>i6;
#else
TC<float>f0;
TC<char>c0;
#endif
#endif
};
void main(void)
{
TC<int>tc;
class CA ca;
}
「#if」いじると警告が出たり出なかったり…。
全体的にテンプレートが複数(多分7つぐらい)
あるとテンプレートの展開が出来なくなり
あるものを使用する形に切り替えられるようだ…。
この時に「インライン関数ではありません」と大量に吐き出すみたい。
またマクロを使用しているいないで変化したりする…。<???
プリプロセッサも一枚かんでいるのか!?
って展開って結局文字置換だから
テンプレート《インライン関数《プリプロセッサ
となっているようだ…。
「\Program Files\Microsoft Visual Studio\VC98\Include」の
中を調べてみると…
ざっと33種類のエラーを抑制している。
つまり「インライン関数ではありません」って当たり前!?
ガ━━(゚Д゚;)━━ン!
ヘルプを調べてみる…
>テンプレートは正式に標準化されていないので、C++ コンパイラのベ
>ンダーによって実装が異なります。
なるふぉど!
>コンパイラは、以前に生成したテンプレートの中に同じものがないと、
>テンプレート クラスまたはテンプレート関数の新しいインスタンスを
>作成します。
…同じ物のはずなのに…!?
>メンバのインスタンスの自動的作成を防ぐには、extern キーワードを
>使います。次に例を示します。
これだぁあ!
>extern キーワードは、クラスの外側で宣言されたメンバ関数だけに適
>用されます。インライン関数には適用されないので、必ずインスタンス
>が作成されます。クラス宣言内で宣言された関数は、インライン関数と
>見なされるので、必ずインスタンスが作成されます。
ガ━━(゚Д゚;)━━ン!
と言う訳でクラス内のテンプレートは、必ずインラインで
展開されるのがお約束のようだ…。
では、「インライン関数ではありません」は何!?
って頭に戻っているし…。
展開する際に何かのセーフティに引っかかり
インライン展開を規制している?
う~ん、仕様と言う名のバグなのだろうか?
知っている人が居れば教えてぇ~!
| 固定リンク
コメント