2014-06-26 1 views
12

Wiki dit:Comment définir une variable externe avec une déclaration?

Le moyen mot-clé extern "déclare sans définir". En d'autres termes, c'est un moyen de déclarer explicitement une variable, ou de forcer une déclaration sans définition. Il est également possible de définir explicitement une variable, c'est-à-dire de forcer une définition. Cela est fait en affectant une valeur d'initialisation à une variable.

Cela signifie, une déclaration extern qui initialise la variable sert de définition pour cette variable. Ainsi,

/* Just for testing purpose only */ 
#include <stdio.h> 
extern int y = 0; 
int main(){ 
    printf("%d\n", y); 
    return 0; 
} 

doit être valide (compiled in C++11). Mais lorsqu'il est compilé avec les options -Wall -Wextra -pedantic -std=c99 dans GCC 4.7.2, produit un avertissement:

[Warning] 'y' initialized and declared 'extern' [enabled by default] 

qui ne devrait pas. Autant que je sache,

extern int y = 0; 

est effectivement la même que

int i = 0; 

Qu'est-ce qui ne va pas ici?

+3

[This] (http://stackoverflow.com/questions/4268589/warning-in-extern-declaration) pourrait également aider. Pas la réponse acceptée, mais celle par [AndreyT] (http://stackoverflow.com/users/187690/andreyt). Notez en particulier la dernière ligne de la réponse: _Désactivez simplement cet avertissement dans les paramètres du compilateur (et, s'il-vous-plaît, écrivez une lettre grossière à ce sujet à l'équipe GCC) ._ – devnull

+0

@devnull; Oui .. – haccks

+0

@devnull; Homme. Tu m'as sauvé. Je jouais avec ça environ une heure! Merci beaucoup :) – haccks

Répondre

5

Les trois versions de la norme - ISO/CEI 9899: 1990, ISO/IEC 9899: 1999 et ISO/IEC 9899: 2011 - contiennent un exemple dans la section avec le titre objet externe définitions (§ 6.7.2 de C90 et §6.9.2 de C99 et C11) qui montre:

Exemple 1

int i1 = 1;  // definition, external linkage 
static int i2 = 2; // definition, internal linkage 
extern int i3 = 3; // definition, external linkage 
int i4;   // tentative definition, external linkage 
static int i5;  // tentative definition, internal linkage 

L'exemple se poursuit, mais la ligne extern int i3 = 3; montre clairement que la norme indique qu'il devrait être autorisé. Notez toutefois que les exemples de la norme ne sont pas techniquement «normatifs» (voir l'avant-propos de la norme); ils ne sont pas une déclaration définitive de ce qui est et n'est pas autorisé. Cela dit, la plupart du temps, la plupart des gens n'utilisent pas extern et un initialiseur.

+0

Je cherchais la section 6.7.9 pour trouver une citation ou un exemple pertinent. – haccks

6

Ce code est parfaitement valide.

Mais tout compilateur est libre d'émettre des diagnostics supplémentaires (ou non) d'information:

(C99, 5.1.1.3p1 fn 8) « Bien sûr, une mise en œuvre est libre de produire un certain nombre de diagnostics comme Tant qu'un programme valide est correctement traduit. "

Quel compilateur ne peut pas faire est de ne pas émettre un diagnostic en cas de violation de contrainte ou de syntaxe.

EDIT:

Comme devnull mis dans les commentaires de question OP, Joseph Myers de l'équipe gcc explique dans un bug report questionnement ce diagnostic:

« Ceci est un avertissement de style de codage - le code est valide, mais extrêmement unidiomatique pour C puisque "extern" est généralement censé signifier que la déclaration ne fournit pas une définition de l'objet. "

+1

Je pense que la partie la plus pertinente du rapport de bug du GCC est: "Ceci est un avertissement de style de codage - le code est valide, mais extrêmement unidiomatique pour C puisque" extern "est généralement censé signifier que la déclaration ne fournit pas une définition de L'object." –

+1

Je pense qu'il pourrait être utile d'ajouter l'exemple (que je cite dans ma réponse) des normes C99/C11 au rapport de bogue. –

+0

@ShafikYaghmour a ajouté une correction pour couvrir une partie du contenu du rapport de bogue – ouah

Questions connexes