C++ Extern / Multiple Definitions

假如想象 提交于 2019-12-14 03:53:53

问题


I am trying to interface to Ada in C++ using externs. What is the difference between these two implementations?

Implementation A

namespace Ada
{
    extern "C"
    {
        int getNumber();
        int index;
        int value;
    }
}

Implementation B

namespace Ada
{
    extern "C"
    {
        int getNumber();
    }
    extern "C" int index;
    extern "C" int value;
}

Both implementations compile just fine. But Impl-A fails to link, I get a multiple definition error for index and value. I'm just trying to understand the differences.


回答1:


extern "C" only conveys the linking conventions to use for the code within the extern "C" block. Anything in that block will be linked against as if it were pure c. Confusingly, extern int is totally different. It means that you promise there is an actual int named index and an actual int named value somewhere, but they cannot be found here. In your implementation-A the ints are actually not extern in the second sense - the extern "C" only implies that they provide a strict c linking convention.

Same keyword but totally different uses, which is unfortunate since it leads to weird issues like this. Mixing them is legal (obviously), but they don't behave together the way that their name implies.

EDIT

See Charle's response for the true definition of the extern weirdness as defined in the C++ standard.




回答2:


A linkage-specifier (i.e. extern "C" or extern "C++") applied to a brace enclosed sequence of declarations has no effect on whether the enclosed declarations are definitions or not, however a linkage-specifier applied to a single declaration is treated as an extern specifier for the purposes of determining whether a declaration is also a definition. (7.5 para 7 of C++03)

So:

extern "C" { int a; } // a is declared and defined

extern "C" int a; // a is just a declaration (as if extern int a;)

extern "C" int a = 0; // a is a definition because of the initializer.



回答3:


I'm not sure why the second works, but you want

namespace Ada
{
    extern "C"
    {
        int getNumber();
        extern int index;
        extern int value;
    }
}

because you only want to declare index and value, not define them. (See this answer for the difference.)



来源:https://stackoverflow.com/questions/3639099/c-extern-multiple-definitions

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!