web-dev-qa-db-fra.com

Utilisation de #pragma en C

Quelles sont certaines utilisations de #pragma en C, avec des exemples?

107
srujan

#pragma est destiné aux directives du compilateur spécifiques à la machine ou au système d’exploitation, c’est-à-dire qu’il indique au compilateur de faire quelque chose, de définir une option, d’agir, de remplacer certaines valeurs par défaut, etc. pouvant s’appliquer ou non à toutes les machines. et systèmes d'exploitation.

Voir msdn pour plus d'informations.

60
Steven A. Lowe

#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 #pragma pack(1), où j'essaie de tirer davantage de mon espace mémoire sur des solutions intégrées, avec des tableaux de structures qui sinon se retrouveraient avec un alignement de 8 octets.

Dommage que nous n'ayons pas encore de #dogma. Ce serait amusant ;)

52
SmacL

J'essayerais 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 voulez les utiliser de manière portable, vous devrez entourer chaque pragma avec une paire #if/#endif. GCC déconseille l’utilisation de pragmas et ne supporte en réalité que certains d’entre eux pour la compatibilité avec d’autres compilateurs; GCC a d'autres moyens de faire la même chose que d'autres compilateurs utilisent les pragmas.

Par exemple, voici comment vous pouvez vous assurer qu’une structure est compactée (c’est-à-dire qu’il n’ya 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 de

#define __attribute__(x)

Considérant que si vous voulez porter le code MSVC, vous devez entourer chaque pragma avec une paire #if/#endif. Pas beau.

32
Adam Rosenfield

En mettant #pragma once en haut de votre fichier d’en-tête s’assurera qu’il n’est inclus qu’une fois. Notez que #pragma once n'est pas standard C99, mais supporté par la plupart des compilateurs modernes.

Une autre solution consiste à utiliser des protecteurs d'inclusion (par exemple, #ifndef MY_FILE #define MY_FILE ... #endif /* MY_FILE */)

15
Schildmeijer

ce que je ressens, c'est #pragma est une directive dans laquelle, si vous voulez que le code soit spécifique à un emplacement. Vous voulez que le compteur de programme lise à partir de l'adresse spécifique où l'ISR est écrit, vous pouvez spécifier l'ISR à cet emplacement en utilisant #pragma vector=ADC12_VECTOR et suivi du nom et de la description de Rotine Interrupt

7
sandeep

Le meilleur conseil que je puisse vous donner est d'examiner 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 le code et les données dans différentes sections ou pour déclarer des gestionnaires d'interruptions. c'est à dire.:

#pragma code BANK1
#pragma data BANK2

#pragma INT3 TimerHandler
5
Justin Love

#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 ex.

#pragma startup func1
#pragma exit func2

Ici, func1 s'exécute avant main et func2 s'exécute ensuite.

REMARQUE: ce code ne fonctionne que dans le compilateur Turbo-C. Pour obtenir cette fonctionnalité dans GCC, vous pouvez déclarer func1 et func2 comme ça:

void __attribute__((constructor)) func1();
void __attribute__((destructor)) func2();
3
Sparkzz

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 des fonctions appelées au démarrage du programme.

#pragma exit nous permet de spécifier des fonctions appelées à la sortie du programme.

#pragma warn indique à l'ordinateur de supprimer ou non tout avertissement.

Beaucoup d'autres #pragma _ styles peuvent être utilisés pour contrôler le compilateur.

3
suresh pareek

Toutes les réponses ci-dessus donnent de bonnes explications pour #pragma mais je voulais ajouter un petit exemple

Je veux juste expliquer un simple OpenMP example qui illustrent certaines utilisations de #pragma faire son travail

OpenMp briefly est une implémentation pour la programmation parallèle multi-plateformes à mémoire partagée (alors on peut dire que c'est machine-specific ou operating-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 que #pragma fait...

il dit au système d'exploitation de lancer le bloc de code sur 4 threads

c'est juste un des many many applications vous pouvez faire avec le petit #pragma

désolé pour l'échantillon extérieur OpenMP

3

Résumer, #pragma indique 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 que GCC se taise à propos des déclarations de fonction implicites, vous pouvez écrire:

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

    Une version plus ancienne de libportable fait ceci de manière portable .

  • #pragma once, lorsqu’il est écrit en haut d’un fichier d’en-tête, le fichier d’en-tête sera inclus une fois. libportablevérifie pour pragma une fois supporté.

2
MD XF