Namespaces
Variants

Implementation defined behavior control

From cppreference.net

El comportamiento definido por la implementación está controlado por la directiva #pragma .

Contenidos

Sintaxis

#pragma pragma_params (1)
_Pragma ( string-literal ) (2) (desde C99)
1) Se comporta de manera definida por la implementación (a menos que pragma_params sea uno de los pragmas estándar mostrados a continuación).
2) Elimina el prefijo de codificación (si existe), las comillas externas y los espacios en blanco iniciales/finales de string-literal , reemplaza cada \" con " y cada \\ con \ , luego tokeniza el resultado (como en fase de traducción 3 ), y luego utiliza el resultado como si fuera la entrada a #pragma en (1) .

Explicación

La directiva pragma controla el comportamiento específico de la implementación del compilador, como deshabilitar advertencias del compilador o cambiar los requisitos de alineación. Cualquier pragma que no sea reconocido es ignorado.

Pragmas estándar

Los siguientes tres pragmas están definidos por el estándar del lenguaje:

#pragma STDC FENV_ACCESS arg (1) (desde C99)
#pragma STDC FP_CONTRACT arg (2) (desde C99)
#pragma STDC CX_LIMITED_RANGE arg (3) (desde C99)

donde arg es ON o OFF o DEFAULT .

1) Si se establece en ON , informa al compilador que el programa accederá o modificará el entorno de punto flotante , lo que significa que se prohíben las optimizaciones que podrían invalidar las pruebas de flags y los cambios de modo (por ejemplo, eliminación global de subexpresiones comunes, movimiento de código y plegado constante). El valor predeterminado está definido por la implementación, generalmente OFF .
2) Permite la contracción de expresiones de punto flotante, es decir, optimizaciones que omiten errores de redondeo y excepciones de punto flotante que se observarían si la expresión se evaluara exactamente como está escrita. Por ejemplo, permite la implementación de ( x * y ) + z con una única instrucción de CPU de multiplicación-acumulación fusionada. El valor predeterminado está definido por la implementación, generalmente ON .
3) Informa al compilador que la multiplicación, división y valor absoluto de números complejos pueden utilizar fórmulas matemáticas simplificadas (x+iy)×(u+iv) = (xu-yv)+i(yu+xv) , (x+iy)/(u+iv) = [(xu+yv)+i(yu-xv)]/(u 2
+v 2
)
, y |x+iy| = x 2
+y 2
, a pesar de la posibilidad de desbordamiento intermedio. En otras palabras, el programador garantiza que el rango de los valores que se pasarán a esas funciones es limitado. El valor predeterminado es OFF .

Nota: los compiladores que no admiten estos pragmas pueden proporcionar opciones equivalentes en tiempo de compilación, como -fcx-limited-range y -ffp-contract de gcc.

Pragmas no estándar

#pragma once

#pragma once es una directiva pragma no estándar que es compatible con la gran mayoría de compiladores modernos . Si aparece en un archivo de cabecera, indica que solo debe analizarse una vez, incluso si se incluye (directa o indirectamente) múltiples veces en el mismo archivo fuente.

El enfoque estándar para prevenir la inclusión múltiple del mismo encabezado es mediante el uso de include guards :

#ifndef LIBRARY_FILENAME_H
#define LIBRARY_FILENAME_H
// contenido del encabezado
#endif /* LIBRARY_FILENAME_H */

Para que todas las inclusiones del encabezado, excepto la primera, en cualquier unidad de traducción sean excluidas de la compilación. Todos los compiladores modernos registran el hecho de que un archivo de encabezado usa una guarda de inclusión y no vuelven a analizar el archivo si se encuentra nuevamente, siempre que la guarda siga definida (ver por ejemplo gcc ).

Con #pragma once , el mismo encabezado aparece como

#pragma once
// contenido del encabezado

A diferencia de los guardas de cabecera, este pragma imposibilita el uso erróneo del mismo nombre de macro en más de un archivo. Por otro lado, dado que con #pragma once los archivos se excluyen basándose en su identidad a nivel del sistema de archivos, esto no puede proteger contra la inclusión de un encabezado dos veces si existe en más de una ubicación en un proyecto.

#pragma pack

Esta familia de pragmas controla la alineación máxima para los miembros de estructuras y uniones definidos posteriormente.

#pragma pack( arg ) (1)
#pragma pack() (2)
#pragma pack(push) (3)
#pragma pack(push, arg ) (4)
#pragma pack(pop) (5)

donde arg es una pequeña potencia de dos y especifica la nueva alineación en bytes.

1) Establece la alineación actual al valor arg .
2) Establece la alineación actual al valor predeterminado (especificado por una opción de línea de comandos).
3) Empuja el valor de la alineación actual en una pila interna.
4) Empuja el valor de la alineación actual en la pila interna y luego establece la alineación actual al valor arg .
5) Extrae la entrada superior de la pila interna y luego establece (restaura) la alineación actual a ese valor.

#pragma pack puede disminuir la alineación de una estructura, sin embargo, no puede hacer que una estructura esté sobrealineada.

Consulte también detalles específicos para GCC y MSVC .

Referencias

  • Estándar C23 (ISO/IEC 9899:2024):
  • 6.10.6 Directiva pragma (p: TBD)
  • 6.10.9 Operador pragma (p: TBD)
  • Estándar C17 (ISO/IEC 9899:2018):
  • 6.10.6 Directiva pragma (p: 127)
  • 6.10.9 Operador pragma (p: 129)
  • Estándar C11 (ISO/IEC 9899:2011):
  • 6.10.6 Directiva pragma (p: 174)
  • 6.10.9 Operador pragma (p: 178)
  • Estándar C99 (ISO/IEC 9899:1999):
  • 6.10.6 Directiva pragma (p: 159)
  • 6.10.9 Operador pragma (p: 161-162)
  • Estándar C89/C90 (ISO/IEC 9899:1990):
  • 3.8.6 Directiva pragma

Véase también

Documentación de C++ para Control de comportamiento definido por la implementación

Enlaces externos

1. Pragmas de C++ en Visual Studio
2. Pragmas aceptados por GCC
3. Descripciones individuales de pragmas y Pragmas estándar en IBM AIX XL C 16.1
4. Apéndice B. Pragmas en la Guía del usuario de Sun Studio 11 C++
5. Pragmas del compilador Intel C++
6. Pragmas del compilador HP aCC