web-dev-qa-db-fra.com

Fonction statique déclarée mais non définie en C ++

Je reçois une erreur du code suivant en utilisant C++.

Main.cpp

#include "file.h"

int main()
{
   int k = GetInteger();
   return 0;
}

Fichier.h

static int GetInteger();

File.cpp

#include "file.h"

static int GetInteger()
{
   return 1;
}

L'erreur que j'obtiens:

Error C2129: static function 'int GetInteger(void)' declared but not defined.

J'ai lu le célèbre article "Organisation du fichier de code en C et C++" , mais je ne comprends pas ce qui ne va pas avec ce code.

61
Sait

En C++, static au niveau global/namespace signifie que la fonction/variable n'est utilisée que dans l'unité de traduction où elle est définie, pas dans d'autres unités de traduction.

Ici, vous essayez d'utiliser une fonction statique d'une autre unité de traduction (Main.cpp) que celui dans lequel il est défini (File.cpp).

Supprimez le static et cela devrait fonctionner correctement.

117
HighCommander4

Changement

static int GetInteger();

à

int GetInteger();

static dans ce cas donne la méthode linkeage interne, ce qui signifie que vous ne pouvez l'utiliser que dans l'unité de traduction où vous la définissez.

Vous le définissez dans File.cpp et essayez de l'utiliser dans main.cpp, mais main n'a pas de définition, car vous l'avez déclaré static.

21
Luchian Grigore

Parce que dans ce cas, static signifie que le nom de la fonction a une liaison interne; que GetInteger dans une unité de traduction n'est pas lié à GetInteger dans toute autre unité de traduction. Le mot clé static est surchargé: dans certains cas, il affecte la durée de vie et dans d'autres, la liaison. C'est particulièrement déroutant ici, car "statique" est aussi le nom d'une vie. Les fonctions et les données déclarées au niveau de l'espace de noms ont toujours une durée de vie statique; lorsque static apparaît dans leur déclaration, il provoque une liaison interne, au lieu de externe.

6
James Kanze

les fonctions déclarées comme étant statiques locales dans le fichier contenant. Par conséquent, vous devez définir la fonction dans le même fichier que ceux qui l'appellent. Si vous souhaitez le rendre appelable à partir d'un autre fichier, vous ne devez PAS le déclarer statique.

3
LeleDumbo

Si tout est dans la même unité de traduction, cela devrait fonctionner. Vous n'avez probablement pas compilé File.cpp dans la même unité que Main.cpp.

g++ -Wall File.cpp Main.cpp

Si chaque fichier est compilé séparément, la fonction doit être créée extern pour être utilisée à partir d'une unité de traduction différente.

extern int GetInteger();

ce qui est le même que

int GetInteger();
2
log0

D'après ma compréhension, les fonctions statiques sont altérées par le nom du fichier dans lequel elles sont définies, donc lorsque vous incluez file.h dans main.cpp, GetInteger () est altéré avec main.cpp bien que vous ayez défini GetInteger () dans file.cpp mais car il est statique, il est également modifié et l'éditeur de liens ne peut pas trouver la définition de GetInteger () car aucune fonction de ce nom n'existe.

Je crois que la leçon apprise est de ne pas déclarer les fonctions statiques dans le fichier d'en-tête car elles ne sont pas destinées à faire partie de l'interface.

2
HBY4PI