none
warning C4251について RRS feed

  • 質問

  • 現在、STLをメンバに含むクラスをコンパイルすると、

    warning C4251の警告が発生します。

    以下の1行を記述することにより、警告の抑止ができることと、

    動作上問題がないことは、確認が取れています。

    #pragma warning(disable:4251)

    【参考文献】

    http://msdn2.microsoft.com/ja-jp/library/esew7y1w.aspx

    http://support.microsoft.com/default.aspx?scid=kb;ja-jp;168958

     

    そこで、ご教授願いたいのですが、

    警告が発生するということは、

    STLをメンバに保有することはNGなのでしょうか?

    それとも、警告は無視してよいのでしょうか?

     

    #pragma once

    #include "TestB.h"
    #include <list>


    class TESTB_API StlDayo
    {
    public:
     StlDayo(void);

     ~StlDayo(void);

     std::list<int> Xyz();

     std::list<int> alalal;
    };

    2006年10月11日 10:21

すべての返信

  • どーも、PATIOです。

    基本的に#pragma warning(disable:4251)のような方法で警告を消すのはあくまでも最終手段なので
    ポンポン使うようは方法ではありません。通常は警告がなくなる方向で修正するのが普通でしょう。
    STLをメンバーに持つ事自体は特に問題ないと思います。
    普通にvectorを使ったりしますから。
    もっと別の所に原因があるような気がします。
    警告を無視したり、プラグマで無理やり消すような事をするのではなく、
    きちんと原因を究明した方が良いと思います。

     追記:
    本当にSTLをメンバーに持っているからその警告が出ているのか確認すべきではないかと
    思います。メンバーに持っているだけなら多分警告が出るような事はないと思います。
    あと、開発環境に関する記述が見当たらないのできちんと開発環境も提示するようにしてください。
    もしかしてですが、このクラスはDLL内のものでexportしているクラスではないですか?
    メンバー変数がpublicで宣言されているから出ているような気もします。
    通常はメンバー変数をprivateにしてpublicなアクセサを提供すると思います。

    2006年10月12日 6:59
  • 返信ありがとうございます。

    ご指摘の通り、記述が不十分でした。

    本クラスは、DLL内のものでexportしているクラスです。

    また、開発環境は、以下の通りです。

    Visual Studio Professional Edition2005


    StlDayo.hの内容

    #pragma once

    #include "TestB.h"
    #include <list>
    #include <vector>


    class TESTB_API StlDayo
    {
    public:
     StlDayo(void);

     ~StlDayo(void);

     std::vector<long> GetLongVec();

    private:
      std::vector<long> longVec; 
    };


    TestB.hの内容

    #ifdef TESTB_EXPORTS
    #define TESTB_API __declspec(dllexport)
    #else
    #define TESTB_API __declspec(dllimport)
    #endif


    コンパイルエラーの内容

    警告 1 warning C4251: 'StlDayo::longVec' : class 'std::vector<_Ty>' は __export キーワードを使って class 'StlDayo' にエクスポートしてください。 c:\documents and settings\xxxxxxx\stldayo.h 18 

    2006年10月12日 7:31
  • ランタイムライブラリをDLLにしていますか?(デバッグ版、リリース版ともに)

    いや、それ以前に vector ってインライン実装だから、エクスポートしちゃいけないんじゃないかな?という気がしなくもない...(^^;

    標準クラスライブラリ(STL)をエクスポートしたコードなんて持ってたかなぁ...

    2006年10月12日 9:35
  • うーん、要するにexportするクラスにstd::vectorを入れちゃってるから駄目なんでしょうねぇ。
    exportしない内部のクラスで使う分にはよいのでしょうけれど。
    ただ思うに例に出しているクラスの実装内容ってあんまり意味ないですよね。
    これだったらストレートにstd::vector<long>を使えば良いだけの話だし。
    意味のない実装で悩んでいるのであれば、あっさり実装方法を変えた方が良いような気がするなぁ。

    結局、std::vectorにexport指定が無いからこういう警告が出るんでしょうねぇ。

    2006年10月13日 7:55
  • PATIOさん。

    回答ありがとうございます。

    根本的な質問になりますが、STLをメンバに保有したクラスをエクスポートすることは、

    よくあることではないのでしょうか?

     

    2006年10月14日 13:30
  • とっちゃんさん

    回答ありがとうございます。

    ランタイムライブラリをDLLにしていますか?(デバッグ版、リリース版ともに)

    との質問の意味がわかりませんでした。

    申し訳ありませんが、もう少し詳細に教えてもらってよいですか?

    また、インライン実装だから、エクスポートしちゃいけないのでは?

    とのご指摘ですが、DLLとそのDLLを使用する側が同時にコンパイルを実施していれば、

    問題ないのでは?

    と、思っているのですが、認識に誤りがあるのでしょうか?

    2006年10月14日 13:33
  • STLフェチ(?)な僕の経験上、それって実害のないwarningだったハズ。

     

    2006年10月14日 15:41
  •  επιστημη さんからの引用

    STLフェチ(?)な僕の経験上、それって実害のないwarningだったハズ。

    実害がない事がハッキリしていれば、#pragmaで警告を無効化するのもありかもしれませんね。
    ただ、これの為に無効化した事で他のところでも警告が出なくなってしまうのはうれしくないかもしれません。
    無害とわかっていれば、出ていてもその部分だけは無視すると言う手もあるかもしれません。

    VC++でMFCを使った開発を行う事が多いので基本的にstd::vectorよりもCArrayクラスを使うケースが
    多い為、問題に突き当たった事がないというのが本当の所なんだと思います。
    何回かvectorを使うケースもありましたが、この場合は内部クラスだったのでexport対象にしていませんでした。

    テンプレートクラスの場合は基本的に宣言時に実体化されるわけだからexportしなくても展開されるはずですしねぇ。

     今回は、STLのこのケースについては目もつぶって良さそうなので有意義な情報が得られました。
    ありがとうございました。

     

    2006年10月16日 6:29
  • とっちゃんです。

     k-suke さんからの引用

    ランタイムライブラリをDLLにしていますか?(デバッグ版、リリース版ともに)

    との質問の意味がわかりませんでした。

    申し訳ありませんが、もう少し詳細に教えてもらってよいですか?

    プロジェクトのプロパティ(ソリューションエクスプローラでプロジェクトの右メニューから表示可能)で

    ツリーの「構成プロパティ」-「C/C++」-「コード生成」を選択すると、「ランタイムライブラリ」という項目があります。

    その構成で、デバッグ版なら「マルチスレッド デバッグ DLL」、リリース版なら「マルチスレッド DLL」となっていれば

    ランタイムライブラリにDLLが利用されます(MFC/ATL のライブラリの指定は、「構成プロパティ」-「全般」にあります)。

     k-suke さんからの引用

    また、インライン実装だから、エクスポートしちゃいけないのでは?

    とのご指摘ですが、DLLとそのDLLを使用する側が同時にコンパイルを実施していれば、

    問題ないのでは?

    と、思っているのですが、認識に誤りがあるのでしょうか?

    ヒープ管理がまたいでる「かもしれない」から、危ないよ。というワーニングメッセージですので、エクスポートする側、される側を同時にビルドすれば問題なしというものではありません。

    それぞれのDLLが同じヒープ境界に所属するかどうかということになりますので、その部分をきちんと確認しておかないとダメよ。

    となります。

    よくわかんないということなら、STLをエクスポートしないもしくは、スタティックライブラリで提供するという方法に切り替えることをお勧めします。

     

    2006年10月16日 7:10