Comment empêcher plusieurs définitions en C?

Je suis un débutant en C et je voulais juste écrire une application console avec Code :: Blocks. Voici le code (simplifié): main.c:

#include  #include  #include "test.c" // include not necessary for error in Code::Blocks int main() { //t = test(); // calling of method also not necessary return 0; } 

test.c:

 void test() {} 

Lorsque j’essaie de générer ce programme, il génère les erreurs suivantes:

 * path * \ test.c | 1 | définition multiple de `_ test '|
 obj \ Debug \ main.o: * chemin * \ test.c | 1 | défini pour la première fois ici |

Je ne parviens pas à définir plusieurs fois le test (bien que je ne sache pas d’où vient le trait de soulignement) et il semble très improbable que la définition soit en quelque sorte incluse deux fois. C’est tout le code qui existe.

J’ai exclu que cette erreur soit due à un conflit de nom avec d’autres fonctions ou fichiers appelés test ou test.c. Notez que le multiple et la première définition sont sur la même ligne dans le même fichier.

Est-ce que quelqu’un sait ce qui cause ceci et ce que je peux faire à ce sujet? Merci!

    En fait, vous comstackz le code source de test.c deux fois:

    • La première fois en compilant test.c lui-même,
    • La deuxième fois lors de la compilation de main.c qui inclut toutes les sources test.c

    Ce dont vous avez besoin dans votre main.c pour utiliser la fonction test() est une simple déclaration, pas sa définition. Ceci est réalisé en incluant un fichier d’en-tête test.h qui contient quelque chose comme:

     void test(void); 

    Ceci informe le compilateur qu’une telle fonction avec des parameters d’entrée et un type de retour existe. Ce que fait cette fonction (tout ce qui se trouve à l’intérieur { et } ) est laissé dans votre fichier test.c

    Dans main.c, remplacez #include "test.c" par #include "test.h" .

    Un dernier point: vos programmes étant plus complexes, vous serez confronté à des situations où des fichiers d’en-tête peuvent être inclus plusieurs fois. Pour éviter cela, les sources d’en-tête sont parfois entourées de définitions de macros spécifiques, telles que:

     #ifndef TEST_H_INCLUDED #define TEST_H_INCLUDED void test(void); #endif 

    Le trait de soulignement y est mis par le compilateur et utilisé par l’éditeur de liens. Le chemin de base est:

     main.c test.h ---> [comstackr] ---> main.o --+ | test.c ---> [comstackr] ---> test.o --+--> [linker] ---> main.exe 

    Votre programme principal doit donc inclure le fichier d’en-tête du module de test, qui ne doit contenir que des déclarations, telles que le prototype de fonction:

     void test(void); 

    Cela permet au compilateur de savoir qu’il existe lors de la compilation de main.c mais que le code lui-même est dans test.c, puis test.o.

    C’est la phase de liaison qui réunit les deux modules.

    En incluant test.c dans main.c, vous définissez la fonction test () dans main.o. Vraisemblablement, vous liez ensuite main.o et test.o, qui contiennent tous deux la fonction test ().

    Vous ne devriez pas inclure d’autres fichiers sources (* .c) dans des fichiers .c. Je pense que vous voulez avoir un fichier d’en- tête ( .h) avec la déclaration DECLARATION of test function et l’avoir DEFINITION dans un fichier .c séparé.

    L’erreur est causée par plusieurs définitions de la fonction test (une dans test.c et une autre dans main.c)

    J’ai eu le même problème et je l’ai résolu de la manière suivante.

    Résoudre comme suit:

    Les déclarations de prototype de fonction et la variable globale doivent être dans le fichier test.h et vous ne pouvez pas initialiser la variable globale dans le fichier d’en-tête.

    Définition de la fonction et utilisation de la variable globale dans le fichier test.c

    si vous initialisez des variables globales dans l’en-tête, l’erreur suivante sera générée

    définition multiple de `_ test ‘| obj \ Debug \ main.o: chemin \ test.c | 1 | défini pour la première fois ici |

    Juste les déclarations de variables globales dans le fichier d’en-tête, aucune initialisation ne devrait fonctionner.

    J’espère que ça aide

    À votre santé

    Le fichier d’implémentation ( test.c ) est ajouté à votre fichier main.c et est respecté séparément. Ainsi, la fonction test a deux définitions: une dans le code object de main.c et une fois dans celui de test.c , ce qui vous donne une violation ODR. Vous devez créer un fichier d’en-tête contenant la déclaration de test et l’inclure dans main.c :

     /* test.h */ #ifndef TEST_H #define TEST_H void test(); /* declaration */ #endif /* TEST_H */ 

    Si vous avez ajouté test.c à votre projet Code :: Blocks, la définition sera vue deux fois – une fois via #include et une fois par l’éditeur de liens. Tu dois:

    • supprimer le #include “test.c”
    • créez un fichier test.h qui contient la déclaration: void test ();
    • inclure le fichier test.h dans main.c

    Si vous utilisez Visual Studio, vous pouvez également faire “#pragma une fois” en haut du fichier d’en-tête pour obtenir le même résultat que “#ifndef …” – le wrapping. Certains autres compilateurs le supportent probablement aussi .. .. Cependant, ne faites pas ceci: D Utilisez le # ifndef-wrapping pour obtenir une compatibilité entre compilateurs. Je voulais juste vous faire savoir que vous pouvez aussi faire #pragma une fois, car vous rencontrerez probablement cette déclaration assez souvent lors de la lecture du code des autres peuples.

    Bonne chance