Visual Studio2015Update1でリンカーエラー
yumetodo opened this issue · comments
何かしらのヘッダーでsprout/math.hpp
を読み込みそれを複数のcppでincludeするとLNK2005がでます。
YSRKEN/KanColleSimulator_KAI@3a1191a
で確認しました。
なお、Clang with Microsoft CodeGen (January 2016) では問題は発生しません。
1>------ ビルド開始: プロジェクト:KCS_CUI, 構成:Debug x64 ------
1> fleet.cpp
1> コードを生成中...
1> コンパイル中...
1> weapon.cpp
1> simulator.cpp
1> other.cpp
1> main.cpp
1> kammusu.cpp
1> コードを生成中...
1>kammusu.obj : error LNK2005: "public: static class sprout::array<float,33> const sprout::math::detail::bernoulli_numbers<float>::table" (?table@?$bernoulli_numbers@M@detail@math@sprout@@2V?$array@M$0CB@@4@B) は既に fleet.obj で定義されています。
1>kammusu.obj : error LNK2005: "public: static class sprout::array<double,51> const sprout::math::detail::bernoulli_numbers<double>::table" (?table@?$bernoulli_numbers@N@detail@math@sprout@@2V?$array@N$0DD@@4@B) は既に fleet.obj で定義されています。
1>kammusu.obj : error LNK2005: "public: static class sprout::array<long double,51> const sprout::math::detail::bernoulli_numbers<long double>::table" (?table@?$bernoulli_numbers@O@detail@math@sprout@@2V?$array@O$0DD@@4@B) は既に fleet.obj で定義されています。
1>main.obj : error LNK2005: "public: static class sprout::array<float,33> const sprout::math::detail::bernoulli_numbers<float>::table" (?table@?$bernoulli_numbers@M@detail@math@sprout@@2V?$array@M$0CB@@4@B) は既に fleet.obj で定義されています。
1>main.obj : error LNK2005: "public: static class sprout::array<double,51> const sprout::math::detail::bernoulli_numbers<double>::table" (?table@?$bernoulli_numbers@N@detail@math@sprout@@2V?$array@N$0DD@@4@B) は既に fleet.obj で定義されています。
1>main.obj : error LNK2005: "public: static class sprout::array<long double,51> const sprout::math::detail::bernoulli_numbers<long double>::table" (?table@?$bernoulli_numbers@O@detail@math@sprout@@2V?$array@O$0DD@@4@B) は既に fleet.obj で定義されています。
1>other.obj : error LNK2005: "public: static class sprout::array<float,33> const sprout::math::detail::bernoulli_numbers<float>::table" (?table@?$bernoulli_numbers@M@detail@math@sprout@@2V?$array@M$0CB@@4@B) は既に fleet.obj で定義されています。
1>other.obj : error LNK2005: "public: static class sprout::array<double,51> const sprout::math::detail::bernoulli_numbers<double>::table" (?table@?$bernoulli_numbers@N@detail@math@sprout@@2V?$array@N$0DD@@4@B) は既に fleet.obj で定義されています。
1>other.obj : error LNK2005: "public: static class sprout::array<long double,51> const sprout::math::detail::bernoulli_numbers<long double>::table" (?table@?$bernoulli_numbers@O@detail@math@sprout@@2V?$array@O$0DD@@4@B) は既に fleet.obj で定義されています。
1>simulator.obj : error LNK2005: "public: static class sprout::array<long double,51> const sprout::math::detail::bernoulli_numbers<long double>::table" (?table@?$bernoulli_numbers@O@detail@math@sprout@@2V?$array@O$0DD@@4@B) は既に fleet.obj で定義されています。
1>simulator.obj : error LNK2005: "public: static class sprout::array<float,33> const sprout::math::detail::bernoulli_numbers<float>::table" (?table@?$bernoulli_numbers@M@detail@math@sprout@@2V?$array@M$0CB@@4@B) は既に fleet.obj で定義されています。
1>simulator.obj : error LNK2005: "public: static class sprout::array<double,51> const sprout::math::detail::bernoulli_numbers<double>::table" (?table@?$bernoulli_numbers@N@detail@math@sprout@@2V?$array@N$0DD@@4@B) は既に fleet.obj で定義されています。
1>weapon.obj : error LNK2005: "public: static class sprout::array<float,33> const sprout::math::detail::bernoulli_numbers<float>::table" (?table@?$bernoulli_numbers@M@detail@math@sprout@@2V?$array@M$0CB@@4@B) は既に fleet.obj で定義されています。
1>weapon.obj : error LNK2005: "public: static class sprout::array<double,51> const sprout::math::detail::bernoulli_numbers<double>::table" (?table@?$bernoulli_numbers@N@detail@math@sprout@@2V?$array@N$0DD@@4@B) は既に fleet.obj で定義されています。
1>weapon.obj : error LNK2005: "public: static class sprout::array<long double,51> const sprout::math::detail::bernoulli_numbers<long double>::table" (?table@?$bernoulli_numbers@O@detail@math@sprout@@2V?$array@O$0DD@@4@B) は既に fleet.obj で定義されています。
1>C:\Users\j.pierreno\Documents\git\KanColleSimulator_KAI\KCS_CUI\x64\Debug\KCS_CUI.exe : fatal error LNK1169: 1 つ以上の複数回定義されているシンボルが見つかりました。
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
とりあえず応急処置しました。 cb801ff
他の箇所でもリンクエラーが出る可能性が考えられるため、近いうち全体的に処置します。
完全特殊化されたクラステンプレートのstaticメンバ変数の定義が重複していると見做されたようですね。
なので、ワークアラウンドとして、完全特殊化でなく部分特殊化になるようにダミーのテンプレート引数を追加しました。
なるほど・・・。
VSにバグレポ投げるべきなんでしょうか?
8e24d45
同様の問題が出そうな箇所をひととおり修正しました。
修正早い・・・。
規格を参照してみましたが、翻訳単位においてクラステンプレートのstaticデータメンバの定義の重複が許されるのは、非特殊化もしくは部分特殊化の場合であるようです。
なので、これについては VC++ の挙動が規格準拠であると考えられます。
なるほど、勉強になりました。ありがとうございます。
このまま問題ないようでしたら一旦閉じます。
はい