C ++ рядний повністю відрізняється від C інлайн .
#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
для даних.
З цього випливає .section name, "flags"MG, @type, entsize, GroupName[, linkage]
. Наприклад, назва розділу .text.c::function()
. axG
означає, що розділ може бути виділений, виконується і в групі, тобто назва групи буде вказана (і немає прапора M, тому не буде вказано енцизіт); @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
на просторі імен див. це та це