@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.
#pragma
directiva sobrevive a la etapa de preprocesamiento. A diferencia de#include
y#define
.Respuestas:
#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.Consulte msdn para obtener más información.
fuente
#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
#dogma
todaví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
/#endif
pair. 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
/#endif
pair. No es bonito.fuente
struct __attribute__((__packed__)) PackedStructure
hack
cuando encuentra un pragma que no reconoce, como solía hacer hace mucho, mucho tiempo, ver#pragma
y GCC , etc.)Ponerlo
#pragma once
en la parte superior de su archivo de encabezado asegurará que solo se incluya una vez. Tenga en cuenta que#pragma once
no 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
#pragma
una 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_VECTOR
y 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,
#pragma
pero quería agregar un pequeño ejemploSolo quiero explicar un
simple OpenMP example
que demuestra algunos usos de#pragma
para hacer su trabajo.vayamos al ejemplo
la salida es
ahora déjame decirte lo que
#pragma
hizo ...le dice al sistema operativo que ejecute algún bloque de código en 4 subprocesos
esto es solo uno de
many many applications
ustedes puede hacer con el pequeño#pragma
perdón por la muestra exterior
OpenMP
fuente
Se trata de una directiva de preprocesador que se puede utilizar para activar o desactivar determinadas funciones.
Es de dos tipos
#pragma startup
,#pragma exit
y#pragma warn
.#pragma startup
nos permite especificar funciones llamadas al inicio del programa.#pragma exit
nos permite especificar funciones llamadas al salir del programa.#pragma warn
le dice a la computadora que elimine cualquier advertencia o no.Se
#pragma
pueden usar muchos otros estilos para controlar el compilador.fuente
#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 ejemploAquí,
func1
corre antesmain
yfunc2
corre después.NOTA: Este código solo funciona en el compilador Turbo-C. Para lograr esta funcionalidad en GCC, puede declarar
func1
yfunc2
así:fuente
En resumen,
#pragma
le dice al compilador que haga cosas. Aquí hay un par de formas en que lo uso:#pragma
se 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
libportable
hace 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.libportable
comprueba si hay pragma una vez compatible.fuente