Hoe voorkom je meerdere definities in C?

Ik ben een C-newbie en ik probeerde net een consoletoepassing te schrijven met Code::Blocks. Hier is de (vereenvoudigde) code:
hoofd.c:

#include <stdio.h>
#include <stdlib.h>
#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() {}

Als ik dit programma probeer te bouwen, geeft het de volgende fouten:

*pad*\test.c|1|meerdere definities van `_ test'|
obj\Debug\main.o:*pad*\test.c|1|eerst hier gedefinieerd|

Er is geen manier dat ik de definitietest vermenigvuldig (hoewel ik niet weet waar het onderstrepingsteken vandaan komt) en het lijkt hoogst onwaarschijnlijk dat de definitie op de een of andere manier twee keer wordt opgenomen. Dit is alle code die er is.

Ik heb uitgesloten dat deze fout te wijten is aan een naamconflict met andere functies of bestanden die test of test.c worden genoemd. Merk op dat het veelvoud en de eerste definitie op dezelfde regel in hetzelfde bestand staan.

Weet iemand wat dit veroorzaakt en wat ik eraan kan doen? Bedankt!


Antwoord 1, autoriteit 100%

Je compileert de broncode van test.ceigenlijk twee keer:

  • De eerste keer dat test.czelf wordt gecompileerd,
  • De tweede keer bij het compileren van main.cdie alle test.c-bronnen bevat.

Wat je nodig hebt in je main.com de functie test()te gebruiken, is een eenvoudige declaratie, niet de definitie ervan. Dit wordt bereikt door een test.hheader-bestand op te nemen dat zoiets bevat als:

void test(void);

Dit informeert de compiler dat een dergelijke functie met invoerparameters en retourtype bestaat. Wat deze functie doet ( alles binnen {en }) wordt achtergelaten in je test.c-bestand.

Vervang in main.c #include "test.c"door #include "test.h".

Een laatste punt: aangezien uw programma’s complexer zijn, zult u te maken krijgen met situaties waarin header-bestanden meerdere keren kunnen worden opgenomen. Om dit te voorkomen, worden koptekstbronnen soms omsloten door specifieke macrodefinities, zoals:

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

Antwoord 2, autoriteit 28%

Het onderstrepingsteken wordt daar geplaatst door de compiler en gebruikt door de linker. Het basispad is:

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

Dus uw hoofdprogramma moet het headerbestand voor de testmodule bevatten, dat alleen uit verklaringen mag bestaan, zoals het functieprototype:

void test(void);

Dit laat de compiler weten dat het bestaat wanneer main.c wordt gecompileerd, maar de eigenlijke code is in test.c, dan test.o.

Het is de verbindingsfase die de twee modules samenvoegt.

Door test.c in main.c op te nemen, definieert u de functie test() in main.o. Vermoedelijk koppel je dan main.o en test.o, die beide de functie test() bevatten.


Antwoord 3, autoriteit 11%

Je mag geen andere bronbestanden (*.c) opnemen in .c-bestanden. Ik denk dat je een headerbestand (.h) wilt hebben met de VERKLARING van de testfunctie, en de DEFINITIE ervan in een apart .c-bestand.

De fout wordt veroorzaakt door meerdere definities van de testfunctie (één in test.c en andere in main.c)


Antwoord 4, autoriteit 6%

Ik had een soortgelijk probleem en heb het op de volgende manier opgelost.

Los als volgt op:

Declaraties van functie-prototype en globale variabele moeten in het test.h-bestand staan en je kunt de globale variabele niet initialiseren in het header-bestand.

Functiedefinitie en gebruik van globale variabele in test.c-bestand

Als u globale variabelen in de koptekst initialiseert, krijgt u de volgende fout

meerdere definities van `_ test’|
obj\Debug\main.o:pad\test.c|1|eerst hier gedefinieerd|

Alleen declaraties van globale variabelen in Header-bestand, geen initialisatie zou moeten werken.

Hopelijk helpt het

Proost


Antwoord 5, autoriteit 4%

Door het implementatiebestand (test.c) op te nemen, wordt het toegevoegd aan uw main.c en daar en dan weer afzonderlijk uitgevoerd. Dus de functie testheeft twee definities — één in de objectcode van main.cen één in die van test.c, die geeft u een ODR-overtreding. U moet een headerbestand maken met de verklaring van testen dit opnemen in main.c:

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

Antwoord 6, autoriteit 4%

Als je test.c aan je Code::Blocks-project hebt toegevoegd, wordt de definitie twee keer weergegeven – één keer via de #include en één keer door de linker. Je moet:

  • verwijder de #include “test.c”
  • Maak een bestandstest.h die de verklaring bevat:
    Void-test ();
  • Neem de bestandstest op in main.c


Antwoord 7, Autoriteit 4%

Als u Visual Studio gebruikt, kunt u ook “#Pragma eens” aan de bovenkant van de headfile doen om hetzelfde te bereiken als de “#ifndef …” – Wikkelen. Sommige andere compilers ondersteunen het waarschijnlijk ook ..
.. Doe dit echter niet: D Stick met de # ifndef-verpakking om cross-compiler compatibiliteit te bereiken. Ik wilde je gewoon laten weten dat je eenmaal #Pragma kunt doen, omdat je waarschijnlijk een beetje deze uitspraak kunt ontmoeten bij het lezen van andere mensencode.

Veel succes met het


Antwoord 8

Ages Hierna vond ik een ander probleem dat dezelfde fout veroorzaakt en nergens het antwoord heeft gevonden. Ik dacht om het hier te zetten voor verwijzing naar andere mensen die hetzelfde probleem ervaren.

Ik heb een functie in een header-bestand gedefinieerd en deze bleef deze fout gooien. (Ik weet dat het niet de juiste manier is, maar ik dacht dat ik het op die manier snel zou testen. )

De oplossing was op alleen plaats een verklaring in het koptekstbestand en de definitie in het CPP-bestand.

De reden is dat header-bestanden niet zijn samengesteld, ze bieden alleen definities.

Other episodes