Namespaces
Variants

Implementation defined behavior control

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 comportamiento definido por la implementación está controlado por la directiva #pragma .

Contenidos

Sintaxis

#pragma parámetros-pragma (1)
_Pragma( literal-de-cadena ) (2) (desde C++11)
1) Se comporta de manera definida por la implementación.
2) Elimina el prefijo L (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 translation phase 3 ), y luego usa 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 no estándar

El estándar del lenguaje ISO C++ no requiere que los compiladores admitan ningún pragma. Sin embargo, varias implementaciones admiten pragmas no estándar:

#pragma STDC

El estándar del lenguaje C ISO requiere que los compiladores de C admitan las siguientes tres pragmas, y algunos proveedores de compiladores C++ las admiten, en diversos grados, en sus frontends de C++:

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

donde arg es ON , 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 anular las pruebas de banderas 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-suma 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 .

El comportamiento del programa es indefinido si cualquiera de los tres pragmas anteriores aparece en cualquier contexto que no sea fuera de todas las declaraciones externas o precediendo a todas las declaraciones explícitas y sentencias dentro de una sentencia compuesta.

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.

#pragma once

#pragma once es un 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 inclusión, 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 clase y unión 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 clase, sin embargo, no puede hacer que una clase esté sobrealineada.

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

Referencias

  • Estándar C++23 (ISO/IEC 14882:2024):
  • 15.9 Directiva pragma [cpp.pragma]
  • Estándar C++20 (ISO/IEC 14882:2020):
  • 15.9 Directiva pragma [cpp.pragma]
  • Estándar C++17 (ISO/IEC 14882:2017):
  • 19.6 Directiva Pragma [cpp.pragma]
  • Estándar C++14 (ISO/IEC 14882:2014):
  • 16.6 Directiva pragma [cpp.pragma]
  • Estándar C++11 (ISO/IEC 14882:2011):
  • 16.6 Directiva pragma [cpp.pragma]
  • Estándar C++98 (ISO/IEC 14882:1998):
  • 16.6 Directiva pragma [cpp.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. Nodos de lanzamiento (incluye pragmas) para HP aCC A.06.25