C ++ inline полностью отличается от C inline .
#include <iostream>
extern inline int i[];
int i [5];
struct c {
int function (){return 1;} //implicitly inline
static inline int j = 3; //explicitly inline
};
int main() {
c j;
std::cout << i;
}
inline
Сам по себе влияет на компилятор, ассемблер и компоновщик. Это директива для компилятора, в которой говорится, что для этой функции / данных следует использовать только символ, если он используется в модуле перевода, и если он есть, то, как и методы класса, указать ассемблеру хранить их в разделе .section .text.c::function(),"axG",@progbits,c::function(),comdat
или .section .bss.i,"awG",@nobits,i,comdat
для данных. Шаблонные экземпляры также идут в своих собственных группах comdat.
Это следует .section name, "flags"MG, @type, entsize, GroupName[, linkage]
. Например, имя раздела .text.c::function()
. axG
означает, что раздел является размещаемым, исполняемым и в группе, т. е. будет указано имя группы (и флаг М отсутствует, поэтому entsize не будет указан); @progbits
означает, что раздел содержит данные и не является пустым; c::function()
это имя группы, и группа имеетcomdat
связь означает, что во всех объектных файлах все разделы, встречающиеся с этим именем группы, помеченные с помощью comdat, будут удалены из конечного исполняемого файла, кроме 1, т.е. компилятор удостоверяется, что в модуле перевода есть только одно определение, а затем говорит ассемблеру поместить он находится в своей собственной группе в объектном файле (1 раздел в 1 группе), а затем компоновщик убедится, что если в каких-либо объектных файлах есть группа с таким же именем, то в окончательный .exe-файл включается только один. Разница между inline
и неиспользованием inline
теперь видна ассемблеру и, как следствие, компоновщику, потому что он не сохраняется в обычном .data
или .text
т. Д. Ассемблером из-за их директив.
static inline
в классе это означает определение типа, а не объявление (позволяет определить статический член в классе) и сделать его встроенным; теперь он ведет себя как выше.
static inline
На область видимости файла влияет только компилятор. Для компилятора это означает: испускать символ для этой функции / данных, только если он используется в модуле перевода, и делать это как обычный статический символ (хранить в .text /.data без директивы .globl). На ассемблере нет теперь никакой разницы между static
иstatic inline
extern inline
является объявлением, которое означает, что вы должны определить этот символ в модуле перевода или выдать ошибку компилятора; если он определен, то рассматривайте его как обычный, inline
и для ассемблера и компоновщика не будет никакой разницы между extern inline
и inline
, так что это только защита компилятора.
extern inline int i[];
extern int i[]; //allowed repetition of declaration with incomplete type, inherits inline property
extern int i[5]; //declaration now has complete type
extern int i[5]; //allowed redeclaration if it is the same complete type or has not yet been completed
extern int i[6]; //error, redeclaration with different complete type
int i[5]; //definition, must have complete type and same complete type as the declaration if there is a declaration with a complete type
Все вышеперечисленное без строки ошибки сворачивается в inline int i[5]
. Очевидно, что если вы сделали extern inline int i[] = {5};
тогдаextern
будут игнорироваться из-за явного определения через присваивание.
inline
в пространстве имен, увидеть это и это