简体   繁体   中英

C++ Extern / Multiple Definitions

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.

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.

A linkage-specifier (ie 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.

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.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM