@smwikipedia, ¿te refieres a que algunos pragmas sobreviven? #pragma once es una directiva de preprocesador, pero #pragma pack es una directiva de compilador
Lewis Kelsey
Respuestas:
66
#pragma es para las directivas del compilador que son específicas de la máquina o del sistema operativo, es decir, le dice al compilador que haga algo, establezca alguna opción, tome alguna acción, anule algunos valores predeterminados, etc.que pueden o no aplicarse a todas las máquinas y operaciones sistemas.
"Eso puede aplicarse o no a todas las máquinas y sistemas operativos". - y diferentes compiladores en la misma máquina. Y lo que puede significar cosas diferentes en diferentes compiladores.
Steve Jessop
53
#pragma se utiliza para hacer algo específico de implementación en C, es decir, ser pragmático para el contexto actual en lugar de ideológicamente dogmático.
El que uso habitualmente es el #pragma pack(1)que trato de sacar más provecho de mi espacio de memoria en soluciones integradas, con matrices de estructuras que, de otro modo, terminarían con una alineación de 8 bytes.
Lástima que no tengamos #dogmatodavía. Eso sería divertido ;)
@Pacerier, normalmente no. Según los comentarios de jalfs, los datos que están alineados en un límite de 4 bytes para procesadores de 32 bits o un límite de 8 bytes para procesadores de 64 bits se cargarán y almacenarán normalmente en una sola operación. Los datos alineados en límites más pequeños requerirán múltiples operaciones para cargar o almacenar. Esto es más lento.
SmacL
35
En general, trataría de evitar el uso de #pragmas si es posible, ya que son extremadamente dependientes del compilador y no portátiles. Si desea usarlos de manera portátil, tendrá que rodear cada pragma con un #if/ #endifpair. GCC desaconseja el uso de pragmas y, en realidad, solo admite algunos de ellos por compatibilidad con otros compiladores; GCC tiene otras formas de hacer las mismas cosas para las que otros compiladores usan pragmas.
Por ejemplo, así es como se aseguraría de que una estructura esté compactada (es decir, sin relleno entre miembros) en MSVC:
Entonces, si quiero compilar el código GCC en MSVC y necesito empaquetar la estructura, ¿cómo lo hago exactamente?
SmacL
2
Para gcc, es struct __attribute__((__packed__)) PackedStructure
Laurent Debricon
#pragma once no es realista "dependiente del compilador y no portátil". Se apoya en las principales plataformas y muchas plataformas no-principales .. en.wikipedia.org/wiki/Pragma_once#Portability
xaxxon
1
Tenga en cuenta que C99 y C11 contienen (C11) §6.10.6 directivas Pragma y ¶1 Cualquier pragma que no sea reconocido por la implementación se ignora. Incluso C90 dice eso, aunque estaba en la sección §6.8.6. (Esto hace que GCC no sea compatible si se ejecuta hackcuando encuentra un pragma que no reconoce, como solía hacer hace mucho, mucho tiempo, ver #pragmay GCC , etc.)
Jonathan Leffler
15
Ponerlo #pragma onceen la parte superior de su archivo de encabezado asegurará que solo se incluya una vez. Tenga en cuenta que #pragma onceno es C99 estándar, pero es compatible con la mayoría de los compiladores modernos.
Una alternativa es usar protectores incluidos (p #ifndef MY_FILE #define MY_FILE ... #endif /* MY_FILE */. Ej. )
lo que siento es #pragmauna directiva en la que, si desea que el código sea específico de la ubicación, diga una situación en la que desea que el contador del programa lea desde la dirección específica donde está escrito el ISR, entonces puede especificar el ISR en esa ubicación usando #pragma vector=ADC12_VECTORy seguido de interrumpir el nombre de rotines y su descripción
Mi mejor consejo es mirar la documentación de su compilador, porque los pragmas son, por definición, específicos de la implementación. Por ejemplo, en proyectos integrados los he usado para localizar código y datos en diferentes secciones, o declarar manejadores de interrupciones. es decir:
#pragma code BANK1
#pragma data BANK2
#pragma INT3 TimerHandler
Todos los pragmas son específicos de la implementación, excepto los pragmas #pragma STDC ..., que están estandarizados en todas las plataformas (además de C99).
Jonathan Leffler
4
Todas las respuestas anteriores son buenas explicaciones, #pragmapero quería agregar un pequeño ejemplo
Solo quiero explicar un simple OpenMP exampleque demuestra algunos usos de #pragmapara hacer su trabajo.
OpenMp brieflyes una implementación para la programación paralela de memoria compartida multiplataforma (entonces podemos decir que es machine-specifico operating-system-specific)
vayamos al ejemplo
#include<stdio.h>#include<omp.h>// compile with: /openmpint main(){#pragma omp parallel num_threads(4){int i = omp_get_thread_num();
printf_s("Hello from thread %d\n", i);}}
la salida es
Hello from thread 0Hello from thread 1Hello from thread 2Hello from thread 3Note that the order of output can vary on different machines.
ahora déjame decirte lo que #pragmahizo ...
le dice al sistema operativo que ejecute algún bloque de código en 4 subprocesos
esto es solo uno de many many applicationsustedes puede hacer con el pequeño#pragma
#pragma startup es una directiva que se utiliza para llamar a una función antes de la función principal y para llamar a otra función después de la función principal, por ejemplo
#pragma startup func1
#pragma exit func2
Aquí, func1corre antes mainy func2corre después.
NOTA: Este código solo funciona en el compilador Turbo-C. Para lograr esta funcionalidad en GCC, puede declarar func1y func2así:
En resumen, #pragmale dice al compilador que haga cosas. Aquí hay un par de formas en que lo uso:
#pragmase puede utilizar para ignorar las advertencias del compilador. Por ejemplo, para hacer que GCC se calle sobre las declaraciones de funciones implícitas, puede escribir:
#pragma once, cuando se escribe en la parte superior de un archivo de encabezado, hará que dicho archivo de encabezado se incluya una vez. libportablecomprueba si hay pragma una vez compatible.
#pragmadirectiva sobrevive a la etapa de preprocesamiento. A diferencia de#includey#define.Respuestas:
#pragmaes para las directivas del compilador que son específicas de la máquina o del sistema operativo, es decir, le dice al compilador que haga algo, establezca alguna opción, tome alguna acción, anule algunos valores predeterminados, etc.que pueden o no aplicarse a todas las máquinas y operaciones sistemas.Consulte msdn para obtener más información.
fuente
#pragmase utiliza para hacer algo específico de implementación en C, es decir, ser pragmático para el contexto actual en lugar de ideológicamente dogmático.El que uso habitualmente es el
#pragma pack(1)que trato de sacar más provecho de mi espacio de memoria en soluciones integradas, con matrices de estructuras que, de otro modo, terminarían con una alineación de 8 bytes.Lástima que no tengamos
#dogmatodavía. Eso sería divertido ;)fuente
pragma(1)mejora realmente la velocidad también? Ver stackoverflow.com/questions/3318410/…En general, trataría de evitar el uso de #pragmas si es posible, ya que son extremadamente dependientes del compilador y no portátiles. Si desea usarlos de manera portátil, tendrá que rodear cada pragma con un
#if/#endifpair. GCC desaconseja el uso de pragmas y, en realidad, solo admite algunos de ellos por compatibilidad con otros compiladores; GCC tiene otras formas de hacer las mismas cosas para las que otros compiladores usan pragmas.Por ejemplo, así es como se aseguraría de que una estructura esté compactada (es decir, sin relleno entre miembros) en MSVC:
Así es como harías lo mismo en GCC:
El código GCC es más portátil, porque si desea compilarlo con un compilador que no sea GCC, todo lo que tiene que hacer es
#define __attribute__(x)Mientras que si desea portar el código MSVC, debe rodear cada pragma con un
#if/#endifpair. No es bonito.fuente
struct __attribute__((__packed__)) PackedStructurehackcuando encuentra un pragma que no reconoce, como solía hacer hace mucho, mucho tiempo, ver#pragmay GCC , etc.)Ponerlo
#pragma onceen la parte superior de su archivo de encabezado asegurará que solo se incluya una vez. Tenga en cuenta que#pragma onceno es C99 estándar, pero es compatible con la mayoría de los compiladores modernos.Una alternativa es usar protectores incluidos (p
#ifndef MY_FILE #define MY_FILE ... #endif /* MY_FILE */. Ej. )fuente
lo que siento es
#pragmauna directiva en la que, si desea que el código sea específico de la ubicación, diga una situación en la que desea que el contador del programa lea desde la dirección específica donde está escrito el ISR, entonces puede especificar el ISR en esa ubicación usando#pragma vector=ADC12_VECTORy seguido de interrumpir el nombre de rotines y su descripciónfuente
Mi mejor consejo es mirar la documentación de su compilador, porque los pragmas son, por definición, específicos de la implementación. Por ejemplo, en proyectos integrados los he usado para localizar código y datos en diferentes secciones, o declarar manejadores de interrupciones. es decir:
fuente
Todas las respuestas anteriores son buenas explicaciones,
#pragmapero quería agregar un pequeño ejemploSolo quiero explicar un
simple OpenMP exampleque demuestra algunos usos de#pragmapara hacer su trabajo.vayamos al ejemplo
la salida es
ahora déjame decirte lo que
#pragmahizo ...le dice al sistema operativo que ejecute algún bloque de código en 4 subprocesos
esto es solo uno de
many many applicationsustedes puede hacer con el pequeño#pragmaperdón por la muestra exterior
OpenMPfuente
Se trata de una directiva de preprocesador que se puede utilizar para activar o desactivar determinadas funciones.
Es de dos tipos
#pragma startup,#pragma exity#pragma warn.#pragma startupnos permite especificar funciones llamadas al inicio del programa.#pragma exitnos permite especificar funciones llamadas al salir del programa.#pragma warnle dice a la computadora que elimine cualquier advertencia o no.Se
#pragmapueden usar muchos otros estilos para controlar el compilador.fuente
#pragma startupes una directiva que se utiliza para llamar a una función antes de la función principal y para llamar a otra función después de la función principal, por ejemploAquí,
func1corre antesmainyfunc2corre después.NOTA: Este código solo funciona en el compilador Turbo-C. Para lograr esta funcionalidad en GCC, puede declarar
func1yfunc2así:fuente
En resumen,
#pragmale dice al compilador que haga cosas. Aquí hay un par de formas en que lo uso:#pragmase puede utilizar para ignorar las advertencias del compilador. Por ejemplo, para hacer que GCC se calle sobre las declaraciones de funciones implícitas, puede escribir:Una versión anterior de
libportablehace esto de forma portátil .#pragma once, cuando se escribe en la parte superior de un archivo de encabezado, hará que dicho archivo de encabezado se incluya una vez.libportablecomprueba si hay pragma una vez compatible.fuente