Quali sono alcuni usi di #pragma
in C, con esempi?
Quali sono alcuni usi di #pragma
in C, con esempi?
Risposte:
#pragma
è per le direttive del compilatore che sono specifiche della macchina o del sistema operativo, cioè dice al compilatore di fare qualcosa, impostare qualche opzione, intraprendere un'azione, sovrascrivere alcune impostazioni predefinite, ecc. che possono o non possono applicarsi a tutte le macchine e al funzionamento sistemi.
Vedi msdn per maggiori informazioni.
#pragma
è usato per fare qualcosa di specifico per l'implementazione in C, cioè essere pragmatico per il contesto attuale piuttosto che ideologicamente dogmatico.
Quello che uso regolarmente è #pragma pack(1)
dove sto cercando di spremere di più dal mio spazio di memoria su soluzioni embedded, con array di strutture che altrimenti finirebbero con un allineamento di 8 byte.
Peccato che non ne abbiamo #dogma
ancora. Sarebbe divertente ;)
pragma(1)
migliora anche la velocità? Vedere stackoverflow.com/questions/3318410/...
In genere cercherò di evitare l'uso di #pragmas se possibile, poiché sono estremamente dipendenti dal compilatore e non portabili. Se vuoi usarli in modo portatile, dovrai circondare ogni pragma con una coppia #if
/ #endif
. GCC scoraggia l'uso di pragmi e in realtà ne supporta solo alcuni per compatibilità con altri compilatori; GCC ha altri modi per fare le stesse cose per cui altri compilatori usano i pragmi.
Ad esempio, ecco come assicurarti che una struttura sia ben compatta (ovvero senza riempimento tra i membri) in MSVC:
#pragma pack(push, 1)
struct PackedStructure
{
char a;
int b;
short c;
};
#pragma pack(pop)
// sizeof(PackedStructure) == 7
Ecco come faresti la stessa cosa in GCC:
struct PackedStructure __attribute__((__packed__))
{
char a;
int b;
short c;
};
// sizeof(PackedStructure == 7)
Il codice GCC è più portabile, perché se vuoi compilarlo con un compilatore non GCC, tutto ciò che devi fare è
#define __attribute__(x)
Considerando che se vuoi portare il codice MSVC, devi circondare ogni pragma con una coppia #if
/ #endif
. Non carino.
struct __attribute__((__packed__)) PackedStructure
hack
quando incontra un pragma che non riconosce, come faceva una volta molto, molto tempo fa - vedi #pragma
e GCC , ecc.)
Mettere #pragma once
in cima al file di intestazione assicurerà che venga incluso solo una volta. Nota che #pragma once
non è C99 standard, ma supportato dalla maggior parte dei compilatori moderni.
Un'alternativa è usare include guards (eg #ifndef MY_FILE #define MY_FILE ... #endif /* MY_FILE */
)
quello che sento è #pragma
una direttiva in cui se vuoi che il codice sia specifico per la posizione, dì una situazione in cui vuoi che il contatore del programma legga dall'indirizzo specifico in cui è scritto l'ISR, puoi specificare l'ISR in quella posizione usando #pragma vector=ADC12_VECTOR
e seguito da interrompi il nome delle rotine e la sua descrizione
Il mio miglior consiglio è di guardare la documentazione del compilatore, perché i pragmi sono per definizione specifici dell'implementazione. Ad esempio, nei progetti incorporati li ho usati per individuare codice e dati in diverse sezioni o dichiarare gestori di interrupt. vale a dire:
#pragma code BANK1
#pragma data BANK2
#pragma INT3 TimerHandler
Tutte le risposte sopra sono belle spiegazioni #pragma
ma volevo aggiungere un piccolo esempio
Voglio solo spiegare un simple OpenMP example
che dimostra alcuni usi #pragma
per fare il suo lavoro
OpenMp
briefly
è un'implementazione per la programmazione parallela multipiattaforma a memoria condivisa (quindi possiamo dire che èmachine-specific
ooperating-system-specific
)
andiamo all'esempio
#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);
}
}
l'uscita è
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.
ora lascia che ti dica cosa ha #pragma
fatto ...
dice al sistema operativo di eseguire alcuni blocchi di codice su 4 thread
questo è solo uno di many many applications
voi che potete fare con il poco#pragma
scusa per il campione esterno OpenMP
Questa è una direttiva del preprocessore che può essere utilizzata per attivare o disattivare determinate funzionalità.
Si tratta di due tipi #pragma startup
, #pragma exit
e #pragma warn
.
#pragma startup
ci permette di specificare le funzioni chiamate all'avvio del programma.
#pragma exit
ci permette di specificare le funzioni chiamate all'uscita dal programma.
#pragma warn
dice al computer di sopprimere o meno qualsiasi avviso.
Molti altri #pragma
stili possono essere usati per controllare il compilatore.
#pragma startup
è una direttiva che viene utilizzata per chiamare una funzione prima della funzione principale e per chiamare un'altra funzione dopo la funzione principale, ad es
#pragma startup func1
#pragma exit func2
Qui func1
corre prima main
e func2
corre dopo.
NOTA: questo codice funziona solo nel compilatore Turbo-C. Per ottenere questa funzionalità in GCC, puoi dichiarare func1
e in func2
questo modo:
void __attribute__((constructor)) func1();
void __attribute__((destructor)) func2();
Per riassumere, #pragma
dice al compilatore di fare cose. Ecco un paio di modi in cui lo uso:
#pragma
può essere utilizzato per ignorare gli avvisi del compilatore. Ad esempio, per far tacere GCC sulle dichiarazioni di funzioni implicite, puoi scrivere:
#pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
Una versione precedente di lo libportable
fa in modo portatile .
#pragma once
, quando scritto all'inizio di un file di intestazione, farà sì che detto file di intestazione venga incluso una volta. libportable
verifica il pragma una volta supportato.
#pragma
la direttiva sopravvive alla fase di pre-elaborazione. A differenza di#include
e#define
.