Attribute specifier sequence (since C++11)
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 ).
|
Si
[[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
|
(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.
[[
noreturn
]]
(C++11)
|
indica que la función no retorna
(especificador de atributo) |
[[
carries_dependency
]]
(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) |
[[
fallthrough
]]
(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) |
[[
maybe_unused
]]
(C++17)
|
suprime las advertencias del compilador sobre entidades no utilizadas, si las hay
(especificador de atributo) |
|
incentiva al compilador a emitir una advertencia si el valor de retorno es descartado
(especificador de atributo) |
|
|
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) |
|
[[
no_unique_address
]]
(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) |
[[
indeterminate
]]
(C++26)
|
especifica que un objeto tiene un valor indeterminado si no está inicializado
(especificador de atributo) |
|
(TM TS)
|
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 . |