Namespaces
Variants

inline specifier

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

El inline especificador, cuando se utiliza en la decl-specifier-seq de una función, declara la función como una función inline .

Una función definida completamente dentro de una definición de clase/struct/union , ya sea una función miembro o una función friend no miembro, es implícitamente una función inline a menos que esté adjunta a un módulo nombrado (desde C++20) .

Una función declarada constexpr o consteval (desde C++20) en su primera declaración es implícitamente una función inline.

Una función eliminada es implícitamente una función inline: su definición (eliminada) puede aparecer en más de una unidad de traducción.

(desde C++11)

El especificador inline , cuando se utiliza en una secuencia-de-especificadores-de-declaración de una variable con duración de almacenamiento estático (miembro estático de clase o variable de ámbito de espacio de nombres), declara la variable como una variable inline .

Un miembro de datos estático declarado constexpr en su primera declaración es implícitamente una variable inline.

(desde C++17)

Contenidos

Explicación

Una función en línea o variable en línea (desde C++17) tiene las siguientes propiedades:

  • La definición de una función inline o variable (since C++17) debe ser accesible en la unidad de traducción donde se accede (no necesariamente antes del punto de acceso).
  • Una función inline o variable (since C++17) con external linkage (por ejemplo, no declarada static ) tiene las siguientes propiedades adicionales:
  • Puede haber más de una definición de una función inline o variable (since C++17) en el programa siempre que cada definición aparezca en una unidad de traducción diferente y (para funciones inline no estáticas y variables (since C++17) ) todas las definiciones sean idénticas. Por ejemplo, una función inline o una variable inline (since C++17) puede definirse en un archivo de cabecera que se incluya en múltiples archivos fuente.
  • Debe declararse inline en cada unidad de traducción.
  • Tiene la misma dirección en cada unidad de traducción.

En una función en línea,

  • Los objetos estáticos locales a función en todas las definiciones de funciones se comparten entre todas las unidades de traducción (todos se refieren al mismo objeto definido en una unidad de traducción).
  • Los tipos definidos en todas las definiciones de funciones también son los mismos en todas las unidades de traducción.

Las variables const inline en el ámbito del espacio de nombres tienen enlace externo por defecto (a diferencia de las variables no inline no volátiles calificadas como const).

(since C++17)

La intención original de la palabra clave inline era servir como un indicador para el optimizador de que la sustitución en línea de una función es preferible sobre la llamada a función, es decir, en lugar de ejecutar la instrucción de llamada a función de la CPU para transferir el control al cuerpo de la función, se ejecuta una copia del cuerpo de la función sin generar la llamada. Esto evita la sobrecarga creada por la llamada a función (pasar los argumentos y recuperar el resultado) pero puede resultar en un ejecutable más grande ya que el código de la función tiene que repetirse múltiples veces.

Dado que la sustitución en línea no es observable en la semántica estándar, los compiladores pueden utilizar la sustitución en línea para cualquier función que no esté marcada como inline , y pueden generar llamadas a funciones para cualquier función marcada como inline . Estas decisiones de optimización no cambian las reglas relativas a definiciones múltiples y estáticos compartidos mencionadas anteriormente.

Debido a que el significado de la palabra clave inline para funciones pasó a significar "se permiten múltiples definiciones" en lugar de "se prefiere la inclusión en línea" desde C++98, ese significado se extendió a las variables.

(since C++17)

Notas

Si una función en línea o variable (since C++17) con enlace externo se define de manera diferente en distintas unidades de traducción, el programa está mal formado, no se requiere diagnóstico.

El inline especificador no puede ser usado con una función o variable (desde C++17) declarada en ámbito de bloque (dentro de otra función).

El especificador inline no puede redeclarar una función o variable (since C++17) que ya fue definida en la unidad de traducción como no-inline.

Las funciones miembro generadas implícitamente y cualquier función miembro declarada como defaulted en su primera declaración son inline como cualquier otra función definida dentro de una definición de clase.

Si una función en línea se declara en diferentes unidades de traducción, los conjuntos acumulados de argumentos predeterminados deben ser los mismos al final de cada unidad de traducción.

En C, las funciones en línea no tienen que declararse inline en cada unidad de traducción (como máximo una puede ser no- inline o extern inline ), las definiciones de funciones no tienen que ser idénticas (pero el comportamiento del programa no está especificado si depende de cuál se llama), y las variables estáticas locales a la función son distintas entre diferentes definiciones de la misma función.

Consulte miembros de datos estáticos para reglas adicionales sobre miembros estáticos en línea.

Las variables en línea eliminan el principal obstáculo para empaquetar código C++ como bibliotecas de solo cabecera.

(desde C++17)
Macro de prueba de características Valor Std Característica
__cpp_inline_variables 201606L (C++17) Variables en línea

Palabras clave

inline

Ejemplo

Encabezado "example.h":

#ifndef EXAMPLE_H
#define EXAMPLE_H
#include <atomic>
// las funciones incluidas en múltiples archivos fuente deben ser inline
inline int sum(int a, int b)
{
    return a + b;
}
// las variables con enlace externo incluidas en múltiples archivos fuente deben ser inline
inline std::atomic<int> counter(0);
#endif

Archivo fuente #1:

#include "example.h"
int a()
{
    ++counter;
    return sum(1, 2);
}

Archivo fuente #2:

#include "example.h"
int b()
{
    ++counter;
    return sum(3, 4);
}

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares publicados anteriormente de C++.

DR Aplicado a Comportamiento publicado Comportamiento correcto
CWG 281 C++98 una declaración de función amiga podía usar el especificador inline
incluso si la función amiga no es una función inline
prohibir tales usos
CWG 317 C++98 una función podía declararse inline incluso si tenía una definición no inline
en la misma unidad de traducción antes de la declaración
el programa está mal
formado en este caso
CWG 765 C++98 un tipo definido en una función inline podría
ser diferente en distintas unidades de traducción
tales tipos son los mismos
en todas las unidades de traducción
CWG 1823 C++98 los literales de cadena en todas las definiciones de una función inline
se compartían entre todas las unidades de traducción
el requisito se elimina debido a
consistencia e implementaciones
CWG 2531 C++17 un miembro de datos static podría ser implícitamente inline incluso si
no estaba declarado constexpr en su primera declaración
no es implícitamente
inline en este caso

Véase también