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в пространстве имен, увидеть это и это