69054


Visual C++ 2019で作成しています。  
以下のようにnamespace直下においた関数では、inlineとstaticの少なくともいずれか一つがないと、ビルドに失敗します。なぜでしょうか。

・Sample10.cpp

[code]

    #include "ABC.cpp"
    int main()
    {
        nspace::show_static_inline();
        nspace::show_static();
        nspace::show_inline();
        return 0;
    }
    
[/code]

・ABC.cpp

[code]

    #include <iostream>
    namespace nspace
    {
        inline static void show_static_inline() {
            std::cout << "show_static_inline" << std::endl;
        }
    
        /*inline*/ static void show_static() {
            std::cout << "show_static" << std::endl;
        }
    
        inline /*static*/ void show_inline() {
            std::cout << "show_inline" << std::endl;
        }
    
        
        //↓ビルドでエラー。
        /*inline static*/ void show() {
            std::cout << "show" << std::endl;
        }   
        /* エラー内容
        1>Sample10.obj : error LNK2005: "void __cdecl nspace::show(void)" (?show@nspace@@YAXXZ) は既に ABC.obj で定義されています。
        1>C:\Users\○○○○\source\repos\Sample10\Debug\Sample10.exe : fatal error LNK1169: 1 つ以上の複数回定義されているシンボルが見つかりました。
        */
    };
    
[/code]


CC BY-SA 4.0
2020-07-28T02:39:38.740
69051
2020-07-28T03:44:40.857
19705
question
c++
namespace直下の関数でinlineかstaticがないとビルドエラーになるのはなぜですか


短い答え：ほとんどすべてのケースで

[code]

    #include "hoge.cpp"
    
[/code]

と書くのは誤りです。

* * *

長い答え：どのようにコンパイルし、どのように **リンク** しているかで話は違ってきますが

[code]

    cl Sample10.cpp ABC.cpp
    
[/code]

のように両方のファイルをコンパイル・リンクしていれば当然の結果です。現に、ウチでは

[code]

    cl Sample10.cpp
    g++ Sample10.cpp
    
[/code]

でどちらもコンパイル・リンク・実行に成功しています。多分実行結果も期待通りでしょう。

`#include` は単にそのファイルの内容をその場所に展開するだけですので `Sample10.cpp` 中に `#include "ABC.cpp"`
と記載してしまうと、そこに `ABC.cpp` の内容がそのまま展開されます。 `cl Sample10.cpp ABC.cpp` とすると結果的に
`ABC.cpp` の内容は２回コンパイルされるので、リンク時に重複エラーになります。 `inline` があるとインライン展開されて重複しない
`static` があると重複を認める、のでどちらもリンクエラーにならないわけです。

ではどう直すかですが、この例の場合 `ABC.cpp` でなくて `ABC.h` (あるいは `ABC.hpp` でも)
にして、コンパイル対象から外すのが良いでしょう。統合開発環境は `cpp` ファイルを自動的にコンパイル対象にするためです。


CC BY-SA 4.0
2020-07-28T03:44:40.857
69054
2020-07-28T03:44:40.857
8589
69051
answer