La déclaration d'une structure dans un en-tête rend mondiale
Il y a trois fichiers:
source1.c
source2.c
l'en-tête.h
Les deux sources-les fichiers inclut l'en-tête.
C'est le code de l'en-tête:
struct
{
int a;
int b
} x;
Ce qui se passe maintenant, c'est que la structure devient mondial et les deux sources-les fichiers partage maintenant la structure appelée x. Pourquoi est-ce arrivé?
Je sais que si vous écrivez le code suivant, il fera deux variables globales. Un pour chaque source fichiers. (ils ne partagent pas les globals)
int x = 0;
Le dernier morceau de code fait sens pour moi, mais je ne comprends vraiment pas l'un avec l'struct..
EDIT:
Hmm tout le monde ici pense que je devrais recevoir des erreurs d'édition de liens. Mon code actuel est pour un système embarqué (nxtOSEK). Je vais essayer de le convertir dans un programme C plus tard.
EDITEDIT:
Je suis de retour avec des exemples réguliers C. Comme vous pouvez le voir, il est non seulement possible avec les structures, mais aussi avec régulièrement des variables.
source1.c
#include "header.h"
int main(void)
{
f();
x = 1;
f();
}
source2.c
#include "header.h"
void f()
{
printf("source2: %i\n", x);
}
en-tête.h
#include <stdio.h>
int x;
Sortie
source2: 0
source2: 1
Remarque que x ne doit pas être déclaré pour qu'il fonctionne ou qu'il donne un éditeur de liens d'erreur comme tout le monde ici dit. (Je ne sais pas pourquoi ça marche avec les embeded système..)
Aussi, il semble que j'ai mal lu, Eric Postpischil réponse qui semble correct.
Eh bien, c'est ce qui se passe.. Imaginez que source1.c est la mise à jour de x régulièrement et ils ont tous les deux l'impression de la valeur actuelle. Vous allez voir que la valeur de source2.c est jamais mis à jour.
Vous avez besoin de montrer compilabe code pour les trois fichiers (avec la structure et à l'int), et la commande(s) que vous avez utilisé pour compiler. Parce que vous ne faites pas ce que je pense que vous êtes en train de faire. Ce que je pense que vous faites dans la
int
cas les résultats dans un éditeur de liens d'erreur. Et apparemment, vous n'êtes pas en faisant ce soit de la answerers pense que vous êtes en train de faire, car ils ont également tous deux en désaccord avec vous quelles sont les causes d'erreurs d'édition de liens et ce qui ne fonctionne pas.Utiliser un débogueur - seule étape à travers le code et vous entrez dans la "Matrice" - il sera clair -- en cristal clair.
OriginalL'auteur Sam Olesen | 2012-09-28
Vous devez vous connecter pour publier un commentaire.
Externe de la déclaration de l'identificateur d'un objet à portée de fichier qui a un initialiseur est un définition. La déclaration
int x = 0;
est une définition, carx
est initialisé.Externe de la déclaration de l'identificateur d'un objet à portée de fichier qui n'a pas un initialiseur est un tentative de définition de. La déclaration
struct {…} x;
est une tentative de définition, carx
n'est pas initialisé.Plusieurs définitions au moment de la liaison de provoquer une erreur.
Plusieurs définitions provisoires au moment de la liaison sont intégrées à une définition unique, qui est initialisé à zéro.
Si vous modifiez
int x = 0;
àint x;
, vous ne serez pas obtenir une erreur de lien. Si vous modifiezstruct {…} x;
àstruct {…} x = {0};
, vous obtiendrez une erreur de lien.OriginalL'auteur Eric Postpischil
Le morceau de code ci-dessous
déclare une variable
x
de typestruct
sans tag. C'est OK pour un static struct que vous prévoyez d'utiliser dans une seule unité de compilation, mais si vous prévoyez de partager unestruct
parmi plusieurs .c fichiers, vous ne devriez pas le faire comme ça. Au lieu de cela, vous devez définir une balise pour votrestruct
ou faire untypedef
pour elle, et de déclarer la variable de ce type séparément, à l'aide de lasrtruct my_struct
syntaxe.Voici un exemple:
Mettre cette
struct
déclaration dans l'en-tête:Mettre cette déclaration de variable dans l' .fichier c:
Maintenant
x
est plus global: vous pouvez accéder à l'intérieur de votre .c fichier, mais il n'est pas visible de l'extérieur. Si vous voulez global, mais d'éviter les erreurs d'édition de liens, ajouterà l'en-tête, et de supprimer
static
de la déclaration dans le .c fichier.Votre structure devient mondial parce que sa déclaration est inséré mot à mot dans chaque .c fichier qui contient l'en-tête. C'est pas un moyen valable de faire une structure globale: si vous inclure l'en-tête avec cette déclaration à partir de plusieurs .c fichiers, vous obtenez les erreurs d'édition de liens parce que de multiples définitions de
x
.Non, c'est la partie étrange. Je n'ai pas de linker des erreurs. - Je faire si j'ai écrit ce qui suit dans l'en-tête: int x = 0;
hmm viens de tester à nouveau avec int x = 0; Il n'est pas de l'éditeur de liens erreurs. Mon mauvais. Mais cela fait du sens parce que les fichiers source ne sais pas au sujet de chaque d'autres variables dans l'en-tête de fichier. Donc pas de conflits. Mais cela n'explique pas pourquoi mon struct variable devient mondial.
Que la chose: la variable est pas dans le fichier d'en-tête autant que le compilateur; il est dans l'en-tête uniquement pour le préprocesseur - le compilateur voit la définition copiée mot pour mot dans le corps de votre .c fichier, donc si vous incluez le même en-tête avec
int x=0;
dans plusieurs .c les fichiers que vous compilez ensemble, vous allez certainement voir une erreur de l'éditeur de liens. Bien sûr, vous ne les verrez pas de linker des erreurs si vous compiler ces fichiers séparément, et ne pas les lier ensemble.OriginalL'auteur dasblinkenlight