216 votes

Effets du mot clé extern C fonctions

En C je n'ai pas remarqué d'effet de la extern mot-clé utilisé avant la déclaration de la fonction. Au début, je pensais que lors de la définition d' extern int f(); dans un fichier unique des forces à mettre en œuvre en dehors de la portée. Cependant j'ai trouvé que deux:

extern int f();
int f() {return 0;}

et

extern int f() {return 0;}

compiler tout simplement beau, avec aucun des avertissements de la gcc. J'ai utilisé gcc -Wall -ansi; il ne serait même pas accepter // commentaires.

Existe-il des effets de l'aide d' extern avant la définition d'une fonction? Ou est-ce juste un mot-clé facultatif, sans effets secondaires pour les fonctions.

Dans ce dernier cas, je ne comprends pas pourquoi le standard, les concepteurs ont choisi de la litière de la grammaire avec superflu des mots-clés.

EDIT: Pour préciser, je sais qu'il y a utilisation d'externes dans des variables, mais je ne demande qu'à propos extern dans les fonctions.

174voto

Tim Post Points 21270

Nous avons deux fichiers, foo.c et d'un bar.c.

Voici foo.c

#include <stdio.h>

volatile unsigned int stop_now = 0;
extern void bar_function(void);

int main(void)
{
  while (1) {
     bar_function();
     stop_now = 1;
  }
  return 0;
}

Maintenant, ici, est bar.c

#include <stdio.h>

extern volatile unsigned int stop_now;

void bar_function(void)
{
   while (! stop_now) {
      printf("Hello, world!\n");
      sleep(30);
   }
}

Comme vous pouvez le voir, nous n'avons pas partagé-tête entre toto.c et d'un bar.c , cependant bar.c a besoin de quelque chose déclarée dans foo.c lors de son lié, et foo.c a besoin d'une fonction à partir de la barre.c lors de son lié.

En utilisant 'extern', vous dites au compilateur que tout ce qui suit, il sera trouvé (non statique) au moment de la liaison.

Il est très utile si vous avez besoin de partager certaines global entre les modules et ne veulent pas mettre / initialiser dans un en-tête.

Techniquement, chaque fonction dans une bibliothèque publique d'en-tête est "extern", cependant leur étiquetage en tant que telle a très peu ou pas de bénéfice, en fonction du compilateur. La plupart des compilateurs peuvent le faire sur leur propre. Comme vous le voyez, ces fonctions sont en fait définis ailleurs.

Dans l'exemple ci-dessus, le main() print " bonjour tout le monde qu'une seule fois, mais continuer à entrer bar_function(). A noter également, bar_function() ne va pas revenir dans cet exemple (puisque c'est juste un exemple simple). Imaginez stop_now être modifié lorsqu'un signal est desservi si cela ne semble pas assez pratiques.

Externes sont très utile pour des choses comme les gestionnaires de signaux, un mutex que vous ne voulez pas mettre dans un en-tête ou de la structure, etc. La plupart des compilateurs de l'optimiser pour s'assurer qu'ils n'ont pas de réserve de la mémoire pour les objets extérieurs, car ils savent qu'ils vont être de le réserver dans le module où l'objet est défini. Cependant, encore une fois, il y a peu de point de en précisant avec les compilateurs modernes lorsque le prototypage des fonctions publiques.

Espérons que cela aide :)

98voto

Rageous Points 858

Que je me souviens de la norme, toutes les déclarations de fonctions sont considérées comme « extern » par défaut, il n’est pas nécessaire de spécifier explicitement.

Cela ne rend pas ce mot-clé inutile puisqu’il peut aussi être utilisé avec variables (et que le cas - c’est la seule solution pour résoudre les problèmes de liaison). Mais avec les fonctions - Oui, c’est facultatif.

19voto

dirkgently Points 56879

L' extern mot-clé prend différentes formes en fonction de l'environnement. Si une déclaration est disponible, l' extern mot-clé prend le lien indiqué plus tôt dans l'unité de traduction. En l'absence d'une telle déclaration, extern spécifie une liaison externe.

static int g();
extern int g(); /* g has internal linkage */

extern int j(); /* j has tentative external linkage */

extern int h();
static int h(); /* error */

Voici les paragraphes pertinents de la C99 projet (n1256):

6.2.2 les identificateurs

[...]

4 Pour un identificateur déclaré avec le stockage de classe spécificateur extern dans un domaine dans lequel une déclaration préalable de cet identifiant est visible,23), si la déclaration préalable précise interne ou liaison externe, le lien entre l'identifiant au plus tard, la déclaration est la même que la lien spécifié à la déclaration préalable. Si aucune déclaration préalable n'est visible, ou si l'état de la déclaration spécifie pas de lien, puis de l'identifiant liaison externe.

5 Si la déclaration d'un identificateur pour une fonction n'a pas de stockage de classe prescripteur, son lien est déterminé exactement comme si elle était déclarée avec le stockage de classe spécificateur extern. Si la déclaration d'un identificateur d'un objet a la portée du fichier et pas de stockage de classe prescripteur, son lien est externe.

3voto

1800 INFORMATION Points 55907

L' extern mot-clé informe le compilateur que la fonction ou la variable a une liaison externe - en d'autres termes, qu'il est visible à partir de fichiers autres que celui dans lequel il est défini. En ce sens, il a le sens opposé à l' static mot-clé. C'est un peu bizarre de mettre des extern au moment de la définition, car pas d'autres fichiers avoir de la visibilité de la définition (ou en seraient la conséquence de multiples définitions). Normalement, vous mettez extern dans une déclaration à un certain point avec la visibilité externe (tel qu'un fichier d'en-tête) et de mettre la définition de l'ailleurs.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X