Quais são alguns usos de #pragma
em C, com exemplos?
Quais são alguns usos de #pragma
em C, com exemplos?
Respostas:
#pragma
é para diretivas de compilador que são específicas da máquina ou do sistema operacional, ou seja, diz ao compilador para fazer algo, definir alguma opção, executar alguma ação, substituir algum padrão, etc. que pode ou não se aplicar a todas as máquinas e operação sistemas.
Veja msdn para mais informações.
#pragma
é usado para fazer algo específico de implementação em C, ou seja, ser pragmático para o contexto atual ao invés de ideologicamente dogmático.
O que eu uso regularmente é #pragma pack(1)
onde estou tentando espremer mais do meu espaço de memória em soluções incorporadas, com matrizes de estruturas que, de outra forma, terminariam com alinhamento de 8 bytes.
Pena que ainda não temos #dogma
. Isso seria divertido ;)
pragma(1)
melhora a velocidade? Consulte stackoverflow.com/questions/3318410/…
Eu geralmente tentaria evitar o uso de #pragmas, se possível, já que eles são extremamente dependentes do compilador e não portáteis. Se você quiser usá-los de forma portátil, terá que envolver cada pragma com um par #if
/ #endif
. O GCC desencoraja o uso de pragmas e realmente só oferece suporte a alguns deles para compatibilidade com outros compiladores; O GCC tem outras maneiras de fazer as mesmas coisas para as quais outros compiladores usam pragmas.
Por exemplo, veja como você pode garantir que uma estrutura seja compactada firmemente (ou seja, sem preenchimento entre os membros) no MSVC:
#pragma pack(push, 1)
struct PackedStructure
{
char a;
int b;
short c;
};
#pragma pack(pop)
// sizeof(PackedStructure) == 7
Veja como você faria a mesma coisa no GCC:
struct PackedStructure __attribute__((__packed__))
{
char a;
int b;
short c;
};
// sizeof(PackedStructure == 7)
O código GCC é mais portátil, porque se você quiser compilá-lo com um compilador não-GCC, tudo que você precisa fazer é
#define __attribute__(x)
Ao passo que, se você deseja portar o código MSVC, deve envolver cada pragma com um par #if
/ #endif
. Feio.
struct __attribute__((__packed__)) PackedStructure
hack
ao encontrar um pragma que não reconhece, como costumava fazer há muito, muito tempo - veja #pragma
e GCC , etc.)
Colocar #pragma once
no topo do arquivo de cabeçalho garantirá que ele seja incluído apenas uma vez. Observe que #pragma once
não é o C99 padrão, mas é compatível com a maioria dos compiladores modernos.
Uma alternativa é usar proteções de inclusão (por exemplo #ifndef MY_FILE #define MY_FILE ... #endif /* MY_FILE */
)
o que eu sinto é #pragma
uma diretiva onde se você quiser que o código seja específico de um local. diga uma situação em que você deseja que o contador do programa leia do endereço específico onde o ISR está escrito, então você pode especificar o ISR naquele local usando #pragma vector=ADC12_VECTOR
e seguido por nome de rotinas de interrupção e sua descrição
Meu melhor conselho é examinar a documentação do seu compilador, porque os pragmas são, por definição, específicos da implementação. Por exemplo, em projetos incorporados, usei-os para localizar código e dados em diferentes seções ou declarar manipuladores de interrupção. ie:
#pragma code BANK1
#pragma data BANK2
#pragma INT3 TimerHandler
Todas as respostas acima são boas explicações para, #pragma
mas eu queria adicionar um pequeno exemplo
Eu só quero explicar um simple OpenMP example
que demonstra alguns usos de #pragma
fazer seu trabalho
OpenMp
briefly
é uma implementação para programação paralela de memória compartilhada multiplataforma (então podemos dizer que émachine-specific
ouoperating-system-specific
)
vamos ao exemplo
#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);
}
}
a saída é
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.
agora deixe-me dizer o que #pragma
fez ...
diz ao sistema operacional para executar algum bloco de código em 4 threads
isso é apenas um de many many applications
vocês pode fazer com o pouco#pragma
desculpe pela amostra externa OpenMP
Esta é uma diretiva de pré-processador que pode ser usada para ligar ou desligar certos recursos.
É de dois tipos #pragma startup
, #pragma exit
e #pragma warn
.
#pragma startup
nos permite especificar funções chamadas na inicialização do programa.
#pragma exit
nos permite especificar funções chamadas na saída do programa.
#pragma warn
diz ao computador para suprimir qualquer aviso ou não.
Muitos outros #pragma
estilos podem ser usados para controlar o compilador.
#pragma startup
é uma diretiva que é usada para chamar uma função antes da função principal e para chamar outra função após a função principal, por exemplo
#pragma startup func1
#pragma exit func2
Aqui, func1
corre antes main
e func2
corre depois.
NOTA: Este código funciona apenas no compilador Turbo-C. Para obter essa funcionalidade no GCC, você pode declarar func1
e func2
assim:
void __attribute__((constructor)) func1();
void __attribute__((destructor)) func2();
Para resumir, #pragma
diz ao compilador para fazer as coisas. Aqui estão algumas maneiras de usá-lo:
#pragma
pode ser usado para ignorar avisos do compilador. Por exemplo, para fazer o GCC calar a boca sobre declarações de funções implícitas, você pode escrever:
#pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
Uma versão mais antiga do libportable
faz isso portavelmente .
#pragma once
, quando escrito no topo de um arquivo de cabeçalho, fará com que o referido arquivo de cabeçalho seja incluído uma vez. libportable
verifica o pragma uma vez que o suporte.
#pragma
A diretiva sobrevive ao estágio de pré-processamento. Ao contrário de#include
e#define
.