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;
}
inline
por 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(),comdat
o.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()
. axG
significa 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); @progbits
significa que la sección contiene datos y no está en blanco; c::function()
es el nombre del grupo y el grupo tienecomdat
enlace, 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 inline
y no usar inline
ahora es visible para el ensamblador y, como resultado, para el vinculador, porque el ensamblador no lo almacena de manera regular .data
o .text
etc. debido a sus directivas.
static inline
en 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 inline
en 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 static
ystatic inline
extern inline
es 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 inline
y para el ensamblador y el enlazador no habrá diferencia entre extern inline
y 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};
, extern
sería ignorado debido a la definición explícita a través de la asignación.
inline
en un espacio de nombres, mira esto y esto