この警告は心配する必要がありますか? 異常な動作を引き起こす可能性があると読みましたか?
これは私がコンパイルしようとしている例です。作成者がオブジェクトをクラスとして宣言しているのに、それを構造体に typedef する理由を誰かが説明してくれませんか? クラスがPODの場合、そうするのは完全に正常ですか?
ありがとう。
この警告は心配する必要がありますか? 異常な動作を引き起こす可能性があると読みましたか?
これは私がコンパイルしようとしている例です。作成者がオブジェクトをクラスとして宣言しているのに、それを構造体に typedef する理由を誰かが説明してくれませんか? クラスがPODの場合、そうするのは完全に正常ですか?
ありがとう。
この警告は、あるタイプの宣言が別のタイプの宣言と矛盾する場合に表示されます(1つは「クラス」、もう1つは「構造体」と言います)。1つの定義規則を考えると、多くても1つを除くすべての宣言は前方宣言でなければなりません。警告は通常、型の前方宣言が間違っていることを示し、通常は単純なタイプミスであり、修正する必要があります。この場合、副作用はないはずですが、実際に修正する必要があります。
ただし、タイプ名の衝突がある場合は、非常に厄介なことが起こる可能性があります(おそらく、「usingnamespace」句またはグローバル名前空間の汚染が原因です)。これらの警告は、2つの異なるライブラリのヘッダーが混在していて、タイプ名が競合していることを示している可能性があります。これらの条件下でコンパイルされたコードは、非常に予期しないことを行う可能性があります。
私のアドバイス-警告が表示された理由を理解し、修正してください。警告がサードパーティ製品にある場合は、それらが修正するように主張します。
上記のこの投稿に対する MSalters のコメントをトップレベルに持ってくるためだけに。名前のマングリングで 'class' または 'struct' キーワードを使用した VC の結果として、見つけるのが難しいリンカ エラーがいくつかありました。
それが問題になると思わない場合は、何時間も頭を悩ませることになります。
この警告については、ブログ投稿「Is C4099 really a sillywarning?」で詳しく説明しています。. 私の結論は、オフにするのが最善だということです。:-) まあ、少なくとも私にとっては。
リチャード・コーデンは正しいです-MSがこの警告を出すのには理由があります。MSコンパイラの場合、装飾された(マングルされた)名前には、どのクラスキー(struct
またはclass
)は型を宣言するために使用されます。あるオブジェクトを引数として取る関数、またはそのオブジェクトを返す関数が、間違ったクラスキーが表示されているときにどこかで参照されている場合、コンパイラエラーは発生しませんが、装飾された名前が異なるため、リンカは文句を言います。リンカエラーは、探しているシンボルのみを表示し、そこでクラスキーの不一致を見逃しやすいため、以前のより詳細なコンパイラ警告が役立ちます。もちろん、2つのバージョンが同じコンパイル単位に表示されない可能性もあります。デフォルトのメンバーの可視性だけが異なると思われる場合は、しばらく頭を悩ませる可能性があります。
マングリングの違いは、C ++標準と競合します。これは、とのような前方宣言struct Foo;
はclass Foo;
同等であるため、同じマングリングを使用する必要があるということです。
これは悪い習慣と考えられていますが、基本的に同じデータ型であるため、クラス定義と構造体宣言を混在させることに問題はないと思います。主な違いは、プライベートであるクラスメンバーとは対照的に、構造体メンバーはデフォルトでパブリックであるということですが、それ以外の点ではメモリレイアウトは同じです。
C ++では、クラスと構造体の唯一の違いは、クラスのメンバー変数、メンバー関数、および基本クラスがデフォルトでプライベートであるのに対し、構造体ではデフォルトでパブリックであるということです。したがって、クラスがPODであるという事実は、ここでは何の違いもありません。
この警告はコードのメンテナンス(定義はどこかで更新されていますが、他の場所では更新されていません)によるものだと思います。そして、警告が消えるようにコードを修正します(たとえば、typedefでクラスを使用します)。
この警告の原因となる可能性のあることの 1 つは、プロジェクトで同じ DLL を参照しているときに、DLL から .tlb ファイルを #import しようとすることです。プロジェクト内から参照として DLL を削除することで、これに関する問題を修正しました。