C ++ en línea es totalmente diferente a C en línea .
#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;
}
inlinepor sí solo afecta al compilador, al ensamblador y al enlazador. Es una directiva para el compilador que dice que solo emite un símbolo para esta función / datos si se usa en la unidad de traducción, y si es así, entonces, como los métodos de clase, dígale al ensamblador que los almacene en la sección .section .text.c::function(),"axG",@progbits,c::function(),comdato.section .bss.i,"awG",@nobits,i,comdat para los datos. Las instancias de plantilla también van en sus propios grupos de comdatos.
Esto sigue .section name, "flags"MG, @type, entsize, GroupName[, linkage]. Por ejemplo, el nombre de la sección es .text.c::function(). axGsignifica que la sección es asignable, ejecutable y en un grupo, es decir, se especificará un nombre de grupo (y no hay un indicador M, por lo que no se especificará ningún tamaño); @progbitssignifica que la sección contiene datos y no está en blanco; c::function()es el nombre del grupo y el grupo tienecomdatenlace, lo que significa que en todos los archivos de objetos, todas las secciones encontradas con este nombre de grupo etiquetado con comdat se eliminarán del ejecutable final, excepto 1, es decir, el compilador se asegura de que solo haya una definición en la unidad de traducción y luego le dice al ensamblador que coloque en su propio grupo en el archivo objeto (1 sección en 1 grupo) y luego el vinculador se asegurará de que si algún archivo objeto tiene un grupo con el mismo nombre, solo incluya uno en el archivo .exe final. La diferencia entre inliney no usar inlineahora es visible para el ensamblador y, como resultado, para el vinculador, porque el ensamblador no lo almacena de manera regular .datao .textetc. debido a sus directivas.
static inlineen una clase significa que es una definición de tipo y no una declaración (permite que se defina un miembro estático en la clase) y que sea en línea; ahora se comporta como arriba.
static inlineen el alcance del archivo solo afecta al compilador. Significa para el compilador: solo emitir un símbolo para esta función / datos si se usa en la unidad de traducción y hacerlo como un símbolo estático regular (almacenar in.text /.data sin la directiva .globl). Para el ensamblador ahora no hay diferencia entre staticystatic inline
extern inlinees una declaración que significa que debe definir este símbolo en la unidad de traducción o lanzar un error del compilador; si está definido, trátelo como regular inliney para el ensamblador y el enlazador no habrá diferencia entre extern inliney inline, por lo que este es solo un protector del compilador.
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
Todo lo anterior sin la línea de error se contrae inline int i[5]. Obviamente, si lo hiciera extern inline int i[] = {5};, externsería ignorado debido a la definición explícita a través de la asignación.
inlineen un espacio de nombres, mira esto y esto