Namespaces
Variants

Attribute specifier sequence (since C23)

From cppreference.net

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

Contenidos

Sintaxis

[[ attr  ]] [[ attr1 , attr2 , attr3 ( args ) ]] [[ attribute-prefix :: attr  ( args ) ]]

Formalmente, la sintaxis es

[[ lista-de-atributos ]] (desde C23)

donde attribute-list es una secuencia separada por comas de cero o más attribute-token s

standard-attribute (1)
attribute-prefix :: identifier (2)
standard-attribute ( argument-list  (opcional) ) (3)
attribute-prefix :: identifier ( argument-list  (opcional) ) (4)

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

1) atributo estándar, como [ [ fallthrough ] ]
2) atributo con un espacio de nombres, como [ [ gnu :: unused ] ]
3) atributo estándar con argumentos, como [ [ deprecated ( "reason" ) ] ]
4) atributo con tanto un espacio de nombres como una lista de argumentos, tal como [ [ gnu :: nonnull ( 1 ) ] ]

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 está permitido por 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. (nota: estos dos atributos son ejemplos ficticios, consulte a continuación para ver 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 precedente.

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

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.

Cada atributo-estándar está reservado para estandarización. Es decir, cada atributo no estándar tiene como prefijo un prefijo-de-atributo proporcionado por la implementación, por ejemplo [[gnu::may_alias]] y [[clang::no_sanitize]] .

Atributos estándar

Solo los siguientes atributos están definidos por el estándar de C. Cada atributo estándar cuyo nombre tiene la forma attr también puede escribirse como __attr__ y su significado no cambia.

[[ deprecated ]] (C23) [[ deprecated (" reason ")]] (C23)
indica que el uso del nombre o entidad declarado con este atributo está permitido, pero se desaconseja por alguna razón
(especificador de atributo)
(C23)
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)
[[ nodiscard ]] (C23) [[ nodiscard (" reason ")]] (C23)
incentiva al compilador a emitir una advertencia si el valor de retorno es descartado
(especificador de atributo)
(C23)
suprime las advertencias del compilador sobre entidades no utilizadas, si las hay
(especificador de atributo)
[[ noreturn ]] (C23) [[ _Noreturn ]] (C23) (deprecated)
indica que la función no retorna
(especificador de atributo)
(C23)
indica que una función no tiene estado, no tiene efectos, es idempotente e independiente
(especificador de atributo)
(C23)
indica que una función no tiene efectos y es idempotente
(especificador de atributo)

Prueba de atributos

__has_c_attribute( attribute-token )

Comprueba la presencia de un token de atributo denominado por attribute-token .

Para los atributos estándar, se expandirá al año y mes en que el atributo fue añadido al borrador de trabajo (ver tabla abajo), la presencia de atributos específicos del proveedor se determina por una constante entera distinta de cero.

__has_c_attribute puede expandirse en la expresión de #if y #elif . Es tratado como una macro definida por #ifdef , #ifndef y defined pero no puede utilizarse en ningún otro lugar.

attribute-token Atributo Valor Estándar
deprecated [[ deprecated ]] 201904L (C23)
fallthrough [[ fallthrough ]] 201904L (C23)
maybe_unused [[ maybe_unused ]] 201904L (C23)
nodiscard [[ nodiscard ]] 202003L (C23)
noreturn
_Noreturn
[[ noreturn ]]
[[ _Noreturn ]]
202202L (C23)
unsequenced [[ unsequenced ]] 202207L (C23)
reproducible [[ reproducible ]] 202207L (C23)

Ejemplo

[[gnu::hot]] [[gnu::const]] [[nodiscard]]
int f(void); // declarar f con tres atributos
[[gnu::const, gnu::hot, nodiscard]]
int f(void); // igual al anterior, pero usa un único especificador
             // de atributo que contiene tres atributos
int f(void) { return 0; }
int main(void)
{
}

Referencias

  • Estándar C23 (ISO/IEC 9899:2024):
  • 6.7.12 Atributos (p: TBD)

Véase también

Documentación de C++ para Secuencia de especificador de atributo

Enlaces externos

1. Atributos en GCC
2. Atributos en Clang