2010-12-06 6 views
4

Je viens de commencer à apprendre le C++. Peut-on expliquer la différence entre les prototypes de fonction C++ suivants?Prototypes de fonction C++

void f(int n); 
extern void f(int n); 
static void f(int n); 

Répondre

11

Les versions vides et externes sont les mêmes. Ils indiquent que la fonction a un lien externe (c'est-à-dire que la définition de la fonction doit provenir d'un autre fichier C ou C++). Statique indique que la fonction a une liaison interne et existera uniquement dans le fichier C++ actuel.

Vous ne voyez presque jamais ces spécificateurs appliqués aux fonctions car 99,9% du temps vous voulez le comportement extern par défaut.

Vous pouvez cependant voir les spécificateurs de stockage static ou extern sur des variables globales, ce qui est souvent fait pour réduire les conflits de noms avec d'autres fichiers dans le même projet. C'est un report de C; Si vous utilisez C++ ce genre de chose devrait être fait avec un espace de noms anonyme au lieu de static.

+4

Légère nitpick: la première n'indique pas * nécessairement * la liaison externe. Il pourrait s'agir simplement d'une déclaration forward pour une définition de fonction qui apparaîtra plus tard dans la même unité de traduction. –

+0

@Charles: Si la fonction existe dans le même fichier d'implémentation, elle sera exportée par ce même fichier pour les autres fichiers à utiliser, auquel cas elle a encore un lien externe. (Bien que vous ayez raison, la fonction elle-même ne doit pas provenir d'une autre unité de traduction) –

+0

A droite, j'aurais dû dire que "n'indique pas nécessairement que la définition de la fonction est attendue dans un autre fichier C ou C++". –

3

Les deux premiers sont la même chose. Le troisième donne f liaison interne, ce qui signifie qu'un fichier source différent peut utiliser le nom f pour être quelque chose de différent.

L'utilisation de static comme dans ce troisième exemple ne doit pas être utilisée. Au lieu d'utiliser un espace de noms anonyme:

namespace { // anonymous 
    void f(int n); 
} 
4

Ceci est plus d'une question en langage C que un C++, mais:

void f(int n); 

Déclare une fonction f qui prend un seul paramètre entier.

extern void f(int n); 

déclare une fonction f qui prend un seul paramètre entier mais existe dans un autre fichier. Le compilateur aura confiance que vous avez implémenté la fonction quelque part. Si l'éditeur de liens ne peut pas le trouver, vous obtiendrez une erreur de l'éditeur de liens.

static void f(int n); 

Déclare une fonction f qui prend un seul paramètre entier. Le mot-clé static rend cela intéressant. Si c'est dans un fichier .cpp, la fonction ne sera visible que pour ce fichier. S'il se trouve dans un fichier .h, chaque fichier .cpp qui inclut cet en-tête créera sa propre copie de cette fonction uniquement accessible à ce fichier d'implémentation.

0

Les deux réponses jusqu'ici ont déconseillé l'utilisation de fonctions statiques. Pourquoi? Ce qui rend

espace de noms {
void f (int n);
}

supérieure à

vide statique f (int n);

? Ce n'est pas plus simple, ce n'est pas plus facile à comprendre ...

+1

Je pense que l'espace de noms anonyme est une meilleure solution pour indiquer le lien interne. Le mot-clé 'static' est déjà surchargé. –

+0

@Charles: Strictement parlant, une fonction dans un espace de noms anonyme a encore un lien externe: http://bytes.com/topic/c/answers/835990-anonymous-namespace-linkage –

+0

@Nemanja: Cela n'a pas vraiment d'importance si ; il est effectivement statique même si le symbole est exporté, car il est soutenu par un véritable espace de noms qui a un nom généré. Vous ne pouvez pas l'appeler à partir d'autres fichiers, et par conséquent, il pourrait aussi bien être statique. –

0

L'espace de noms anonyme est une solution plus universelle et plus propre, vous pouvez y avoir des fonctions, des variables, des classes. Et static est beaucoup trop surchargé, dans certains contextes signifiant lien interne, dans d'autres la durée de vie statique.
Il existe cependant un inconvénient de l'espace de noms anonyme.En raison de la liaison externe, la section exportée de vos fichiers objet/bibliothèque va gonfler avec tous ces longs noms <unique namespace name>::<function> qui ne seraient pas là sont ils étaient statiques.

Questions connexes