Pourquoi le compilateur limite-t-il toujours l’initialisation de la variable globale par une valeur constante?

Laissez-moi illustrer ceci,

int a = 100; int b = a; int main(int argc, char **argv, char ** env) { printf("The value of b=%d\r\n",b); return 0; } 

Maintenant, j’obtiens l’erreur de compilation comme prévu.

 [joshis1@localhost global_var]$ gcc global_var.c -o global_var.out global_var.c:4:1: error: initializer element is not constant int b = a; ^ 

Ce que je veux apprendre ici, c’est pourquoi je reçois l’erreur? pourquoi le compilateur restreint cette opération. Je comprends que les variables globales initialisées sont stockées dans des segments de données. Le compilateur aurait d’abord pu résoudre la valeur de a, puis aurait atsortingbué la même valeur à b. Pourquoi il manque cette fonctionnalité? Est-ce complexe pour le compilateur? Y at-il une raison derrière cette fonctionnalité ou juste un piège de C?

La documentation officielle, extraite de la ligne 1644, 6.7.8 Initialisation , indique:

Toutes les expressions dans un initialiseur pour un object ayant une durée de stockage statique doivent être des expressions constantes ou des littéraux de chaîne.

Pourquoi la règle existe est une question plus difficile – peut-être que vous dites que c’est difficile pour le compilateur. En C ++, une telle expression est valide, mais un initialiseur global peut invoquer des constructeurs, etc., alors que pour C, les objects globaux sont évalués à la phase de compilation. int b = a; est évaluable au moment de la compilation, mais qu’en est-il de int b = a + c; ? int b = pow(a, 2); ? Où vous arrêteriez-vous? C décide que ne pas vous permettre de commencer est la meilleure solution.

De votre commentaire:

… comment puis-je forcer le compilateur à faire ce travail?

Vous ne pouvez pas forcer le compilateur à accepter ce que vous avez, mais vous pouvez atteindre votre objective en définissant la valeur que vous souhaitez atsortingbuer aux deux variables.

 #define INITIAL_VALUE_FOR_A 100 int a = INITIAL_VALUE_FOR_A; int b = INITIAL_VALUE_FOR_A; 

Maintenant, si vous devez modifier la valeur initiale, il vous suffit de la modifier à un endroit.

C est portable pour de très petites machines. L’évaluation d’expressions qui ne sont pas constantes nécessite le code d’exécution, dans une fonction. En programmation intégrée, vous ne souhaiterez peut-être aucune fonction (ou code) que vous n’ayez pas explicitement programmée.

Votre compilateur évaluera probablement l’initialiseur en tant qu’extension de langue, s’il est configuré avec des options différentes. Si cela échoue, vous pouvez essayer le C ++ (même juste le sous-ensemble de type C) ou un autre langage faisant plus de choses que vous aimez: v).

D’autres ont expliqué pourquoi les initialiseurs ne peuvent généralement pas être des expressions arbitraires.

Le moyen de ” forcer le compilateur à accepter le code ” est de changer le code . La manière la plus efficace d’initialiser arbitrairement les variables de liaison externe (vulgo: “global”) du fichier, est d’appeler une fonction d’initialisation au début de main () qui effectue toute l’initialisation dans l’ordre requirejs:

 #include  int a; int b; void init(void) { a = 100; b = a; } int main(int argc, char **argv) { init(); printf("The value of b=%d\n", b); return 0; }