web-dev-qa-db-fra.com

Une fonction statique a-t-elle besoin du mot-clé statique pour le prototype en C?

Mon livre de programmation C dit que lorsque je veux créer une fonction statique, je dois mettre le mot-clé statique devant la fonction définition. Il ne mentionne rien explicitement sur le prototype. De plus, les exemples n'utilisent pas de prototypes et placent simplement les fonctions statiques en haut du fichier (afin qu'ils n'aient pas besoin de prototypes, je suppose).

Donc, une fonction statique a-t-elle besoin du mot-clé statique pour le prototype? Ou dois-je seulement le mettre devant la définition?

45
w1res

Non. Une déclaration de fonction (prototype ou même la définition) peut omettre le mot clé static si elle vient après une autre déclaration de la même fonction avec static.

S'il y a une déclaration static d'une fonction, sa première déclaration doit être static.

Il est défini dans ISO/IEC 9899: 1999, 6.7.1:

Si la déclaration d'un identificateur de portée de fichier pour une [...] fonction contient le spécificateur de classe de stockage static, l'identifiant a un lien interne.

[...]

Pour un identifiant déclaré avec le spécificateur de classe de stockage extern dans une étendue dans laquelle une déclaration préalable de cet identifiant est visible, si la déclaration préalable spécifie un lien interne ou externe, le lien de l'identifiant à la déclaration ultérieure est le même que le lien spécifié dans la déclaration préalable.

[...]

Si la déclaration d'un identifiant pour une fonction n'a pas de spécificateur de classe de stockage, sa liaison est déterminée exactement comme si elle avait été déclarée avec le spécificateur de classe de stockage extern.

[...]

Si, au sein d'une unité de traduction, le même identifiant apparaît avec une liaison interne et externe, le comportement n'est pas défini.

Ainsi, par exemple c'est valable:

static void foo(void);
void foo(void);
static void foo(void) { }

Celui-là aussi:

static void foo(void) { }
void foo(void);

static void bar(void);
void bar(void) {}

Mais ce code est incorrect:

void foo(void);
static void foo(void) { }

Normalement, vous aurez et devriez également avoir le static dans les prototypes (car ils viennent généralement en premier).

48
undur_gongor