Le problème est que, avec un nombre entier, le compilateur généralement de ne jamais créer une adresse en mémoire de la constante. Il n'existe pas au moment de l'exécution, et chaque utilisation est incorporé dans le code environnant. Il peut encore décider de lui donner un emplacement de mémoire - si son adresse est déjà pris (ou s'il est passé par const référence à une fonction), qu'il doit. Afin de donner une adresse, il doit être défini dans certains de l'unité de traduction. Et dans ce cas, vous avez besoin de séparer la déclaration de la définition, car sinon il serait d'obtenir défini dans plusieurs unités de traduction.
À l'aide de g++ sans optimisation (-O0
), elle est automatiquement inlines constante des variables de type entier mais pas constant, les valeurs doubles. À la hausse des niveaux d'optimisation (par exemple, -O1
), il inlines constante doubles. Ainsi, le code suivant compile en -O1
, mais PAS à l' -O0
:
// File a.h
class X
{
public:
static const double d = 1.0;
};
void foo(void);
// File a.cc
#include <stdio.h>
#include "a.h"
int main(void)
{
foo();
printf("%g\n", X::d);
return 0;
}
// File b.cc
#include <stdio.h>
#include "a.h"
void foo(void)
{
printf("foo: %g\n", X::d);
}
Ligne de commande:
g++ a.cc b.cc -O0 -o a # Linker error: ld: undefined symbols: X::d
g++ a.cc b.cc -O1 -o a # Succeeds
Pour un maximum de portabilité, vous devez déclarer vos variables dans les fichiers d'en-tête et de le définir une fois dans certains fichier source. Sans optimisation, ce ne sera pas nuire à la performance, puisque vous n'êtes pas à l'optimisation de toute façon, mais avec les optimisations activées, ce qui peut nuire à la performance, car le compilateur ne peut plus inline ces constantes dans d'autres fichiers source, sauf si vous activez l'option "tout le programme d'optimisation".