C ++ Extern / Multiple Definitions - PullRequest
       2

C ++ Extern / Multiple Definitions

3 голосов
/ 03 сентября 2010

Я пытаюсь взаимодействовать с Ada в C ++, используя externs.В чем разница между этими двумя реализациями?

Реализация A

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

Реализация B

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

Обе реализации компилируются просто отлично.Но Impl-A не может соединиться, я получаю многократную ошибку определения для index и value .Я просто пытаюсь понять разницу.

Ответы [ 3 ]

7 голосов
/ 04 сентября 2010

extern "C" передает только соглашения о связывании, которые будут использоваться для кода внутри внешнего блока "C".Все в этом блоке будет связано, как если бы это было чисто c.Смущает то, что extern int совершенно другой.Это означает, что вы обещаете, что где-то есть фактический именованный индекс и фактическое именованное значение, но их здесь нет.В вашей реализации-A целые числа на самом деле не являются внешними во втором смысле - внешняя буква «С» подразумевает только то, что они обеспечивают строгое соглашение о связывании с.приводит к странным проблемам, как это.Смешивание их является законным (очевидно), но они не ведут себя так, как предполагает их название.

РЕДАКТИРОВАТЬ

См. Ответ Чарль для истинного определениявнешняя странность, как определено в стандарте C ++.

7 голосов
/ 04 сентября 2010

A спецификатор связи (то есть extern "C" или extern "C++"), примененный к заключенной в скобки последовательности объявлений, не влияет на то, являются ли вложенные объявления определениями или нет, однако связь -спецификатор , примененный к одному объявлению, рассматривается как спецификатор extern в целях определения того, является ли объявление также определением. (7.5, параграф 7 C ++ 03)

Итак:

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 голосов
/ 03 сентября 2010

Я не уверен, почему второй работает, но вы хотите

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

, потому что вы хотите объявить index и value, не определяют им.(См. этот ответ для различия.)

...