Это может помочь понять, почему A<p>{};
не допускается, если вы предполагаете, что p
инициализируется некоторой функцией
const char* p = getP();
, где getP()
определяет ее результат по некоторым данным времени выполнения, для например, путем чтения конфигурационного файла.
Разрешения на язык:
extern "C" {
#include "foo.h"
}
, Что, если foo.h содержит что-то, что требует связи C++?
void f_plain(const char *);
extern "C++" void f_fancy(const std::string &);
Это - то, как Вы угождаете компоновщику.
Нет никакой настоящей причины для использования extern "C++"
. Это просто делает явными связь, которая является неявным значением по умолчанию. Если у Вас есть класс, где у некоторых участников есть экстерн "C" связь, можно пожелать явного состояния, что другие - экстерн "C++".
Примечание, которое Стандарт C++ определяет синтаксически extern "anystring"
. Это только дает формальные значения extern "C"
и extern "C++"
. Поставщик компилятора свободен определить extern "Pascal"
или даже extern "COM+"
, если им нравится.
Я не уверен, почему необходимо было бы сделать это, но согласно этот статья от Sun, можно использовать экстерна "C++" в блоке экстерна "C", чтобы определить, что определенные функции в группе функций "C" имеют собственную связь C++.
extern "C" {
void f(); // C linkage
extern "C++" {
void g(); // C++ linkage
extern "C" void h(); // C linkage
void g2(); // C++ linkage
}
extern "C++" void k();// C++ linkage
void m(); // C linkage
}
C и C++ используют отличающийся правила искажения имени . По существу экстерн "C" говорит компилятору C++ называть функцию, как C назвал бы его.
Два предположения:
extern "C"
блок, можно получить связь языка C++ снова путем определения вложенного extern "C++"
. C++
связь, потому что это - документ, определяющий C++. Кто находится в лучшем положении для определения C++
связь языка, чем он сам. Это также предусматривает полноту. То же соглашение как с signed/unsigned
. Read этот ответ , который объясняет extern "LanguageName"
(т.е. GCC имеет extern "Java"
), также.
Это определяет который конвенция ссылки использовать. Большинство языков знает, как связаться с функцией стиля "C".
Вам нужно это в двух случаях:
:
// declared in function.h
void f1(void);
Ваш код C - на самом деле другие языки в состоянии связаться с функцией C - не будет в состоянии связаться с ним, потому что имя в объектной таблице будет использовать конвенцию C++.
, Если Вы пишете
extern "C" void f1(void);
Теперь связывающиеся работы, потому что это использует конвенцию C.
Короткий ответ - то, что можно использовать экстерна C, чтобы сказать компилятору не использовать искажение имени. Это означает, что можно соединить биты C и кода C++ в том же проекте.
Причина № 1 я использую экстерна "C", состоит в том, чтобы избежать правил искажения имени C++. Это очень важно, если Вы работаете на языке .NET и хотите к PInvoke в конкретную собственную функцию. Единственный способ сделать это с отключенным искажением имени.
экстерн "C" используется, чтобы сказать, что функция C++ должна иметь связь C. То, что это означает, является иждивенцем реализации, но обычно это выключает искажение имени C++ (и таким образом перегружаясь и строгую проверку типа). Вы используете его, когда у Вас есть функция C++, Вы хотите позвониться от кода C:
extern "C" void Foo(); // can be called easily from C
Что касается экстерна "C++", я никогда не видел его в реальном коде, хотя Стандарт C++ позволяет его. Я предполагаю, что это нет.