2008-10-24 14 views
86

¿Cuáles son algunos usos de #pragma en C, con ejemplos?Uso de #pragma en C

+0

La directiva '# pragma' sobrevive a la etapa de procesamiento previo. A diferencia de '# include' y' # define'. – smwikipedia

Respuesta

11

Poner #pragma once en la parte superior del archivo de encabezado se asegurará de 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 utilizar incluyen guardias (por ejemplo #ifndef MY_FILE #define MYFILE ... #endif)

45

#pragma se utiliza para hacer algo específico de la implementación en C, es decir, ser pragmáticos para el contexto actual en lugar de ideológicamente dogmática.

La que utilizo regularmente es #pragma pack(1) en la que trato de exprimir más espacio de mi memoria en soluciones integradas, con arreglos de estructuras que de otra manera terminarían con una alineación de 8 bytes.

Lástima que todavía no tengamos un #dogma. Eso sería divertido;)

+36

necesitaríamos #karma para anular (ejecutar) #dogma –

+0

@ShaneMacLaughlin, ¿'pragma (1)' realmente no mejora la velocidad también? Consulte http://stackoverflow.com/questions/3318410/pragma-pack-effect#comment31382945_3318475 – Pacerier

+3

@Pacerier, normalmente no. Según los comentarios de jalfs, los datos alineados en un límite de 4 bytes para procesadores de 32 bits o límites de 8 bytes para procesadores de 64 bits generalmente se cargarán y almacenarán en una sola operación. Los datos que están alineados en límites más pequeños tomarán múltiples operaciones para cargar o almacenar. Esto es mas lento –

49

#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 medida, anule algunas predeterminadas, etc. que puede o no aplicarse a todas las máquinas y sistemas operativos.

Consulte msdn para obtener más información.

+9

"que puede o no aplicarse a todas las máquinas y sistemas operativos". - y diferentes compiladores en la misma máquina. Y que podría significar cosas diferentes en diferentes compiladores. –

5

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 ubicar códigos y datos en diferentes secciones, o declaro manejadores de interrupciones. es decir .:

#pragma code BANK1 
#pragma data BANK2 

#pragma INT3 TimerHandler 
+3

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). –

24

Me lo general tratar de evitar el uso de #pragmas si es posible, ya que son extremadamente compilador dependiente y no portátil. Si desea usarlos de forma portátil, deberá rodear cada pragma con un par # if/# endif. GCC desalienta el uso de pragmas, y realmente solo admite algunos de ellos para la compatibilidad con otros compiladores; GCC tiene otras formas de hacer las mismas cosas que otros compiladores usan pragmas.

Por ejemplo, aquí te mostramos cómo asegurar que una estructura está lleno de fuerza (es decir, sin relleno entre los miembros) en MSVC:

#pragma pack(push, 1) 
struct PackedStructure 
{ 
    char a; 
    int b; 
    short c; 
}; 
#pragma pack(pop) 
// sizeof(PackedStructure) == 7

Así es como usted haría lo mismo en GCC:

struct PackedStructure __attribute__((__packed__)) 
{ 
    char a; 
    int b; 
    short c; 
}; 
// sizeof(PackedStructure == 7)

El código de GCC es más portátil, ya que si se desea compilar que con un compilador GCC no, todo lo que tiene que hacer es

#define __attribute__(x)

Considerando que si desea portar el código MSVC, debe rodear cada pragma con un par # if/# endif. No es bonito.

+2

Entonces, si quiero compilar el código de GCC en MSVC y necesito empacar la estructura, ¿cómo exactamente lo hago? –

+2

Para gcc, es 'struct __attribute __ ((__ packed__)) PackedStructure' –

+0

#pragma una vez no es realistamente" dependiente del compilador y no portátil ". Es compatible con todas las plataformas principales y muchas plataformas no principales. Https://en.wikipedia.org/wiki/Pragma_once#Portability – xaxxon

7

lo que siento es #pragma es una directiva donde si desea que el código sea específico de la ubicación .desea una situación en la que desea que el contador del programa lea desde la dirección específica donde se escribe el ISR, entonces puede especificar ISR en ese ubicación usando #pragma vector=ADC12_VECTOR y seguido por interrupt rotines name y su descripción

3

Esta es una directiva de preprocesador que se puede usar para activar o desactivar ciertas funciones.

Es de dos tipos #pragma startup, #pragma exit y #pragma warn.

#pragma startup nos permite especificar las funciones solicitadas al iniciar el programa.

#pragma exit nos permite especificar las funciones solicitadas al salir del programa.

#pragma warn le dice a la computadora que elimine cualquier advertencia o no.

Muchos otros estilos #pragma se pueden utilizar para controlar el compilador.

2

#pragma startup es una directiva que se utiliza para llamar a una función antes de la función principal y llamar a otra función después de la función principal, p.

#pragma startup func1 
#pragma exit func2 

Aquí, func1 ejecuta antes main y func2 carreras después.

NOTA: Este código funciona solo en el compilador Turbo-C. Para conseguir esta funcionalidad en GCC, se puede declarar func1 y func2 así:

void __attribute__((constructor)) func1(); 
void __attribute__((destructor)) func2(); 
2

Todas las respuestas anteriores hacen buenas explicaciones para #pragma pero quería una añada ejemplo pequeña

sólo quiero explicar un simple OpenMP example que demuestran algunos usos de #pragma a hacer su trabajo

OpenMP briefly es una implementación para múltiples plataformas de memoria compartida programación paralela (entonces podemos decir que es machine-specific o operating-system-specific)

vamos al ejemplo

#include <stdio.h> 
#include <omp.h>// compile with: /openmp 

int 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 0 
Hello from thread 1 
Hello from thread 2 
Hello from thread 3 

Note that the order of output can vary on different machines. 

ahora déjenme lo #pragma lo dijeron ...

le dice a la O S para ejecutar el algún bloque de código en 4 hilos de

esto es sólo una de many many applications que puede hacer con el pequeño #pragma

pena por la muestra fuera OpenMP

2

Para resumir, #pragma cuenta la compilador para hacer cosas. Aquí hay un par de maneras que lo uso:

  • #pragma se puede utilizar para ignorar las advertencias del compilador.Por ejemplo, para hacer que GCC dejar de hablar de las declaraciones de funciones implícitas, se puede escribir:

    #pragma GCC diagnostic ignored "-Wimplicit-function-declaration" 
    

    una versión anterior de libportable hace esto portably.

  • #pragma once, cuando se escribe en la parte superior de un archivo de encabezado, hará que dicho archivo de encabezado se incluya una vez. libportablechecks para soporte pragma una vez.

Cuestiones relacionadas