Namespaces
Variants

Attribute specifier sequence (since C++11)

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

Introduce atributos definidos por la implementación para tipos, objetos, código, etc.

Contenidos

Sintaxis

[[ lista-de-atributos ]] (desde C++11)
[[ using espacio-de-nombres-de-atributo : lista-de-atributos ]] (desde C++17)

donde attribute-list es una secuencia separada por comas de cero o más attribute s (posiblemente terminando con puntos suspensivos ... indicando una pack expansion )

identificador (1)
espacio-de-nombres-atributo :: identificador (2)
identificador ( lista-de-argumentos  (opcional) ) (3)
espacio-de-nombres-atributo :: identificador ( lista-de-argumentos  (opcional) ) (4)

donde attribute-namespace es un identifier y argument-list es una secuencia de tokens donde paréntesis, corchetes y llaves están balanceados ( balanced-token-seq ).

1) Atributo simple, como [ [ noreturn ] ] .
2) Atributo con un espacio de nombres, como [ [ gnu :: unused ] ] .
3) Atributo con argumentos, como [ [ deprecated ( "because" ) ] ] .
4) Atributo con un espacio de nombres y una lista de argumentos.

Si using namespace: aparece al principio de una lista de atributos, ningún otro atributo en la lista de atributos puede especificar un espacio de nombres: el espacio de nombres especificado en un using se aplica a todos ellos:

[[using CC: opt(1), debug]] // same as [[CC::opt(1), CC::debug]]
[[using CC: CC::opt(1)]] // error: cannot combine using and scoped attribute
(desde C++17)

Explicación

Los atributos proporcionan la sintaxis estándar unificada para extensiones de lenguaje definidas por la implementación, como las extensiones de lenguaje GNU e IBM __attribute__((...)) , la extensión de Microsoft __declspec() , etc.

Un atributo puede utilizarse en casi cualquier parte del programa C++, y puede aplicarse a casi todo: a tipos, a variables, a funciones, a nombres, a bloques de código, a unidades de traducción completas, aunque cada atributo particular solo es válido donde lo permite la implementación: [[expect_true]] podría ser un atributo que solo puede usarse con un if , y no con una declaración de clase. [[omp::parallel()]] podría ser un atributo que se aplica a un bloque de código o a un for loop, pero no al tipo int , etc (nótese que estos dos atributos son ejemplos ficticios, véase más abajo para los atributos estándar y algunos no estándar).

En las declaraciones, los atributos pueden aparecer tanto antes de toda la declaración como directamente después del nombre de la entidad que se declara, en cuyo caso se combinan. En la mayoría de las otras situaciones, los atributos se aplican a la entidad inmediatamente anterior.

El alignas especificador es parte de la secuencia de especificadores de atributos, aunque tiene una sintaxis diferente. Puede aparecer donde aparecen los atributos [[...]] y puede mezclarse con ellos (siempre que se use donde alignas está permitido).

Dos tokens consecutivos de corchete izquierdo ( [[ ) solo pueden aparecer al introducir un especificador de atributo o dentro de un argumento de atributo.

void f()
{
    int y[3];
    y[[] { return 0; }()] = 1;  // error
    int i [[cats::meow([[]])]]; // OK
}

Además de los atributos estándar enumerados a continuación, las implementaciones pueden admitir atributos no estándar arbitrarios con comportamiento definido por la implementación. Todos los atributos desconocidos para una implementación se ignoran sin causar un error. (since C++17)

Un atributo sin attribute-namespace y un attribute-namespace cuyo nombre sea std o std seguido de uno o más dígitos está reservado para futuras estandarizaciones. Es decir, cada atributo no estándar está en el attribute-namespace proporcionado por la implementación, por ejemplo [[gnu::may_alias]] , [[clang::trivial_abi]] , y [[msvc::noop_dtor]] .

(since C++20)

Atributos estándar

Los siguientes atributos están definidos por el estándar de C++.

Los atributos estándar no pueden ser ignorados sintácticamente: no pueden contener errores de sintaxis, deben aplicarse al objetivo correcto, y las entidades en los argumentos deben ser ODR-use .

Los atributos estándar tampoco pueden ser ignorados semánticamente: el comportamiento con todas las instancias de un atributo estándar particular eliminadas habría sido un comportamiento conforme para el programa original con el atributo presente.

(C++11)
indica que la función no retorna
(especificador de atributo)
(C++11) (eliminado en C++26)
indica que la cadena de dependencias en release-consume std::memory_order se propaga hacia y desde la función
(especificador de atributo)
[[ deprecated ]] [[ deprecated (" reason ")]]
(C++14) (C++14)
indica que el uso del nombre o entidad declarado con este atributo está permitido, pero se desaconseja por alguna razón
(especificador de atributo)
(C++17)
indica que la continuación desde la etiqueta case anterior es intencional y no debe ser diagnosticada por un compilador que advierte sobre continuaciones
(especificador de atributo)
(C++17)
suprime las advertencias del compilador sobre entidades no utilizadas, si las hay
(especificador de atributo)
[[ nodiscard ]] [[ nodiscard (" reason ")]]
(C++17) (C++20)
incentiva al compilador a emitir una advertencia si el valor de retorno es descartado
(especificador de atributo)
(C++20) (C++20)
indica que el compilador debe optimizar para el caso donde una ruta de ejecución a través de una sentencia es más o menos probable que cualquier otra ruta de ejecución
(especificador de atributo)
(C++20)
indica que un miembro de datos no estático no necesita tener una dirección distinta de todos los demás miembros de datos no estáticos de su clase
(especificador de atributo)
[[ assume ( expression )]]
(C++23)
especifica que la expresión siempre evaluará a true en un punto dado
(especificador de atributo)
(C++26)
especifica que un objeto tiene un valor indeterminado si no está inicializado
(especificador de atributo)
indica que la definición de la función debe ser optimizada para invocación desde una sentencia sincronizada
(especificador de atributo)

Notas

La presencia de cada atributo individual en una plataforma determinada puede verificarse con __has_cpp_attribute la macro del preprocesador.

Macro de prueba de características Valor Estándar Característica
__cpp_attributes 200809L (C++11) Atributos
__cpp_namespace_attributes 201411L (C++17) Atributos para espacios de nombres

Ejemplo

[[gnu::always_inline]] [[gnu::hot]] [[gnu::const]] [[nodiscard]]
inline int f(); // declarar f con cuatro atributos
[[gnu::always_inline, gnu::const, gnu::hot, nodiscard]]
int f(); // igual al anterior, pero usa un único especificador de atributo que contiene cuatro atributos
// C++17:
[[using gnu : const, always_inline, hot]] [[nodiscard]]
int f[[gnu::always_inline]](); // un atributo puede aparecer en múltiples especificadores
int f() { return 0; }
int main() {}

Informes de defectos

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

DR Aplicado a Comportamiento publicado Comportamiento correcto
CWG 2079 C++11 [[ no podía aparecer dentro de un argumento de atributo permitido
CWG 2538 C++11 no estaba claro si los atributos estándar pueden ignorarse sintácticamente prohibido
CWG 2695 C++11 no estaba claro si los atributos estándar pueden ignorarse semánticamente prohibido
P2156R1 C++11 cada atributo estándar debía aparecer como máximo una vez en una attribute-list no requerido

Véase también

__has_cpp_attribute - verifica la presencia de un atributo
C documentation para Attributes specifier sequence

Enlaces externos

1. Atributos en GCC . Estos atributos pueden usarse como [[gnu::...]] , Ver SO .
2. Atributos en Clang .
3. Atributos en MSVC .