Quelles sont certaines utilisations de #pragma
C, avec des exemples?
Quelles sont certaines utilisations de #pragma
C, avec des exemples?
Réponses:
#pragma
est pour les directives du compilateur qui sont spécifiques à la machine ou au système d'exploitation, c'est-à-dire qu'il dit au compilateur de faire quelque chose, de définir une option, de prendre une action, de remplacer certaines valeurs par défaut, etc. qui peuvent ou non s'appliquer à toutes les machines et à l'exploitation systèmes.
Voir msdn pour plus d'informations.
#pragma
est utilisé pour faire quelque chose de spécifique à l'implémentation en C, c'est-à-dire être pragmatique pour le contexte actuel plutôt que idéologiquement dogmatique.
Celui que j'utilise régulièrement est celui #pragma pack(1)
où j'essaie de tirer davantage de mon espace mémoire sur des solutions embarquées, avec des tableaux de structures qui, autrement, se retrouveraient avec un alignement de 8 octets.
Dommage que nous n'en ayons pas #dogma
encore. Ce serait amusant ;)
pragma(1)
réellement la vitesse aussi? Voir stackoverflow.com/questions/3318410/…
J'essaierais généralement d'éviter l'utilisation de #pragmas si possible, car ils sont extrêmement dépendants du compilateur et non portables. Si vous souhaitez les utiliser de manière portable, vous devrez entourer chaque pragma d'une paire #if
/ #endif
. GCC déconseille l'utilisation de pragmas, et ne prend en charge que certains d'entre eux pour la compatibilité avec d'autres compilateurs; GCC a d'autres façons de faire les mêmes choses que les autres compilateurs utilisent les pragmas.
Par exemple, voici comment vous assurer qu'une structure est compacte étroitement (c'est-à-dire pas de remplissage entre les membres) dans MSVC:
#pragma pack(push, 1)
struct PackedStructure
{
char a;
int b;
short c;
};
#pragma pack(pop)
// sizeof(PackedStructure) == 7
Voici comment vous feriez la même chose dans GCC:
struct PackedStructure __attribute__((__packed__))
{
char a;
int b;
short c;
};
// sizeof(PackedStructure == 7)
Le code GCC est plus portable, car si vous voulez le compiler avec un compilateur non-GCC, tout ce que vous avez à faire est
#define __attribute__(x)
Alors que si vous voulez porter le code MSVC, vous devez entourer chaque pragma d'une paire #if
/ #endif
. Pas beau.
struct __attribute__((__packed__)) PackedStructure
hack
lorsqu'il rencontre un pragma qu'il ne reconnaît pas, comme il le faisait jadis il y a très, très longtemps - voir #pragma
et GCC , etc.)
Mettre #pragma once
en haut de votre fichier d'en-tête garantira qu'il n'est inclus qu'une seule fois. Notez que ce #pragma once
n'est pas le C99 standard, mais pris en charge par la plupart des compilateurs modernes.
Une alternative consiste à utiliser des gardes inclus (par exemple #ifndef MY_FILE #define MY_FILE ... #endif /* MY_FILE */
)
ce que je ressens est #pragma
une directive où si vous voulez que le code soit spécifique à l'emplacement. dites une situation où vous voulez que le compteur de programme lise à partir de l'adresse spécifique où l'ISR est écrit, vous pouvez spécifier ISR à cet emplacement en utilisant #pragma vector=ADC12_VECTOR
et suivi de interrompre le nom des rotines et sa description
Mon meilleur conseil est de regarder la documentation de votre compilateur, car les pragmas sont par définition spécifiques à l'implémentation. Par exemple, dans des projets intégrés, je les ai utilisés pour localiser du code et des données dans différentes sections, ou pour déclarer des gestionnaires d'interruption. c'est à dire:
#pragma code BANK1
#pragma data BANK2
#pragma INT3 TimerHandler
Toutes les réponses ci-dessus font de belles explications pour #pragma
mais je voulais ajouter un petit exemple
Je veux juste expliquer un simple OpenMP example
qui montre quelques utilisations de #pragma
pour faire son travail
OpenMp
briefly
est une implémentation pour la programmation parallèle multi-plateforme à mémoire partagée (alors nous pouvons dire que c'estmachine-specific
ouoperating-system-specific
)
allons à l'exemple
#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 sortie est
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.
maintenant laissez-moi vous dire ce #pragma
que ...
il dit au système d'exploitation d'exécuter le bloc de code sur 4 threads
c'est juste l'un de many many applications
vous peut faire avec le peu#pragma
désolé pour l'échantillon extérieur OpenMP
Il s'agit d'une directive de préprocesseur qui peut être utilisée pour activer ou désactiver certaines fonctionnalités.
Il est de deux types #pragma startup
, #pragma exit
et #pragma warn
.
#pragma startup
nous permet de spécifier les fonctions appelées au démarrage du programme.
#pragma exit
nous permet de spécifier les fonctions appelées à la sortie du programme.
#pragma warn
indique à l'ordinateur de supprimer ou non tout avertissement.
De nombreux autres #pragma
styles peuvent être utilisés pour contrôler le compilateur.
#pragma startup
est une directive qui est utilisée pour appeler une fonction avant la fonction principale et pour appeler une autre fonction après la fonction principale, par exemple
#pragma startup func1
#pragma exit func2
Ici, func1
s'exécute avant main
et func2
s'exécute après.
REMARQUE: ce code fonctionne uniquement dans le compilateur Turbo-C. Pour réaliser cette fonctionnalité dans GCC, vous pouvez déclarer func1
et func2
aimer ceci:
void __attribute__((constructor)) func1();
void __attribute__((destructor)) func2();
Pour résumer, #pragma
dit au compilateur de faire des choses. Voici quelques façons dont je l'utilise:
#pragma
peut être utilisé pour ignorer les avertissements du compilateur. Par exemple, pour faire taire GCC des déclarations de fonctions implicites, vous pouvez écrire:
#pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
Une ancienne version de le libportable
fait de manière portable .
#pragma once
, lorsqu'il est écrit en haut d'un fichier d'en-tête, ce fichier d'en-tête sera inclus une fois. libportable
vérifie le support pragma une fois.
#pragma
directive survit à l'étape de prétraitement. Contrairement à#include
et#define
.