C++ аргумент ссылкой и связь C

Я встретился с работой (с XLC8 и компиляторами MSFT9) часть кода, содержа файл C++ с функцией, определяемой со связью C и ссылочным аргументом. Это прослушивает меня, поскольку ссылками является C++ только. Рассматриваемая функция вызвана из кода C, где это объявляется как взятие аргумента указателя тому же типу вместо ссылочного аргумента.

Упрощенный пример:

Файл C++:

extern "C" void f(int &i)
{
    i++;
}

C файл:

void f(int *);

int main()
{
    int a = 2;
    f(&a);
    printf("%d\n", a);  /* Prints 3 */
}

Теперь, слово на улице то, что большинство компиляторов C++, под капотом, ссылки реализации точно так же, как указатель. Похож на это это и просто чистая удача причина этот код работы, или это говорит где-нибудь в спецификации C++, чем результат состоит в том при определении функции со ссылочным аргументом и связью C? Я не смог найти любую информацию об этом.

13
задан Peter Mortensen 19 November 2010 в 10:53
поделиться

4 ответа

Моя копия n3000.pdf (из здесь ), в разделе 7.5— Спецификации связей :

9 . Связь из C ++ с объектами, определенными в другие языки и определенные объекты в C ++ с других языков есть определяется реализацией и зависит от языка. Только там, где стратегии размещения объектов из двух языковые реализации похожи достаточно, чтобы такая связь могла быть достигнута.

Поскольку C и C ++ - разные языки, это означает, что вы не можете полагаться на эту «особенность» общих компиляторов.

Сильнее - примечание 5 в том же разделе (выделено мной) :

Если два объявления объявляют функции с таким же именем и список-типов-параметров (8.3.5), который должен быть члены того же пространства имен или объявлять объекты с тем же именем в быть членами одного и того же пространства имен и декларации дают имена различные языковые связи, программа плохо сформирована; нет диагностики требуется, если появляются объявления в разных единицах перевода .

Итак, я бы сказал, что то, что вы сделали, не гарантирует работу в соответствии со стандартом, и компилятор не обязан печатать диагностику для приведенного вами примера, потому что объявления находятся в разных единицах перевода .

FYI, это "работает для меня" с gcc и g ++ версии 4.2.1 на Snow Leopard.

5
ответ дан 1 December 2019 в 22:57
поделиться

Во многих случаях, но не все, ссылка может быть реализована с помощью указателя с автоматическим разыменованием. То, что какой-либо конкретный компилятор обрабатывает функцию со связью C и параметром ссылки таким образом, не гарантируется в стандарте C ++, и вы должны рассматривать это как деталь реализации.

Нетрудно написать функцию пересылки, которая принимает указатель и вызывает вашу функцию, если вам нужно сделать это, не полагаясь на детали реализации:

void real_f(int& n) {
  n++;
}
extern "C" void f(int* p) { // called from C code
  real_f(*p);
}
11
ответ дан 1 December 2019 в 22:57
поделиться

Ссылка - это альтернативное имя для объекта. Технически в C нет ничего, что могло бы напрямую отображаться на ссылку C ++.

Очевидная реализация ссылки - это (постоянный) указатель, ссылка на который разыменовывается каждый раз, когда он используется. Итак, в зависимости от того, как ваш компилятор реализует ссылки, ваш код может работать. Но это не так.

Решение состоит в том, чтобы написать функцию C, которая принимает либо реальный объект, либо указатель на этот объект, и вызывает функцию C ++ из этого.

3
ответ дан 1 December 2019 в 22:57
поделиться

Вот что Бьярн Страуструп должен сказать о ссылках:

" Большинство ссылок реализуется с помощью указателя переменная; это ссылка обычно занимает одно слово в памяти. Однако ссылка, которая используется исключительно локально, может - и часто удаляется - оптимизатором ».

Например:

 struct S 
 { 
    int a;
    int b[100]; 
 };  // just an example

 void do_something(const vector<S>& v)
 {
    for (int i=0; i<v.size(); ++i)
    {
        int(&p)[100] = v[i].b;
        for (int j=0; j<100; ++j) 
           cout <<p[j];
    }
 }

В этом случае p не нужно сохранять в памяти (возможно, он просто существует в регистре, может быть, он исчезает в инструкциях).

0
ответ дан 1 December 2019 в 22:57
поделиться