[C] Multiple definition of..

Pagina: 1
Acties:
  • 119 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 19-09 15:50
Ik heb nog een probleempje waar ik niet uitkom en dat is het volgende:
Ik heb voor het gemak het probleem even geprobeerd te isoleren met zo weinig mogelijk code.
main.c
C:
1
2
3
4
5
6
7
#include "test.h"

int main(void)
{
    test(&strA[0]);
    return 0;
}


test.c
C:
1
2
3
4
5
6
7
8
9
#include <stdio.h>
#include <string.h>
#include "test.h"

int test(char *pArray)
{
    printf("%s", pArray);
    return 0;
}


test.h
C:
1
2
3
4
5
6
7
8
9
10
#ifndef _TEST_H
#define _TEST_H

// zomaar wat waarden:
char    strA[] = {0x30, 0x31, 0x32}; 
char    strB[] = {0x30, 0x31, 0x32};

int test(char *pArray);

#endif // _TEST_H


ik compileer dit met:
arm-linux-gcc -Wall main.c test.c -o virm

Dit geeft een error:
multiple definition of strA
first defined here
multiple definition of strB
first defined here
exit status

Waar gaat het fout. Ik heb echt geen flauw idee.
Het gaat erom dat ik een array declare die ik voor in test.c en in main.c kan gebruiken. Ik dacht dat het misschien met het ''extern" zou werken maar ook levert niets op.

Acties:
  • 0 Henk 'm!

  • scorpie
  • Registratie: Augustus 2001
  • Laatst online: 19-09 20:57

scorpie

Supra Addict

In test.h staat 2x onder elkaar:
C:
1
char    strA[] = {0x30, 0x31, 0x32};  

je definieert dus 2x de variabele strA als een char, buiten het feit dat je de regel eronder gewoon kunt weglaten, zou je ook in de 2e regel alleen het woordje char weg kunnen laten.

wil een Toyota Supra mkIV!!!!! | wil een Yamaha YZF-R{1,6} | wil stiekem ook een Ducati
"Security is just a state of mind"
PSN: scorpie | Diablo 3: scorpie#2470


Acties:
  • 0 Henk 'm!

  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 19-09 15:50
scorpie schreef op dinsdag 16 januari 2007 @ 11:36:
In test.h staat 2x onder elkaar:
C:
1
char    strA[] = {0x30, 0x31, 0x32};  

je definieert dus 2x de variabele strA als een char, buiten het feit dat je de regel eronder gewoon kunt weglaten, zou je ook in de 2e regel alleen het woordje char weg kunnen laten.
Euh was is een simpel overtik foutje. :P
Ik heb op de eigenlijke laptop waarop ik code geen internet. Ik heb dat al geedit.

De ene is strA andere strB.

Als ik echter de regels met de declaratie verplaats vanuit test.h naar bovenin main.c compileert alles prima.

[ Voor 9% gewijzigd door Gehakt op 16-01-2007 11:45 ]


Acties:
  • 0 Henk 'm!

  • Brakkie
  • Registratie: Maart 2001
  • Niet online

Brakkie

blaat

Ik heb 0 verstand van C maar je include test.h in main.c en in test.c. Zorgt dat niet voor een dubbele definitie?

Systeem | Strava


Acties:
  • 0 Henk 'm!

  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 19-09 15:50
Nee daar zijn de header guards voor als het goed is.

Acties:
  • 0 Henk 'm!

Verwijderd

In test.h moet je test als extern declareren

Acties:
  • 0 Henk 'm!

  • igmar
  • Registratie: April 2000
  • Laatst online: 03-09 22:58

igmar

ISO20022

Het waarom is vrij simpel : de compiler compileer eerst main.c naar objectcode (main.o), en include daarvoor test.h (inc de array definities). Vervolgens wordt hetzelfde gedaan voor test.c. Dar levert je dus twee object files op : test.o en main.o. Die worden vervolgens gelinked. Aangezien beide files afzonderlijk gecompileerd worden werken je guards dus niet, en de linker komt er vervolgens achter dat beide object files de betreffende array bevatten.

Oplossing : In 1 van de .c files de arrays extern declareren, en in de andere .c file de arrays zelf.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Het is handig om te weten wat definities en declaraties zijn. Een declaratie kun je zien als een hint aan de compiler in de trand van "er bestaat een X met type Y". Een definitie is echter "hier is een X met type Y". Declaraties en definities kun je hebben voor variabelen, functies en structs.

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// declaraties
struct aap; // van een struct
void noot(); // van een functie
extern int mies; // van een variabele

// definities
struct aap
{
    int a, b;
};

void noot()
{
    puts("hoi\n");
}

int mies;


Van variabelen en (non-inline) functies mag je maar 1 definitie in je programma hebben. Jij hebt van strA en strB nu 2 definities - eentje in main.c en eentje in test.c (omdat ze allebei test.h includen die die definitie geeft)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 19-09 15:50
Kijk na de laatste 2 reply's snap ik het principe.

Ik heb hetn u op weten te lossen door ze te defineren boven in test.c en te declareren als extern in main.h

Thanx :>

[ Voor 97% gewijzigd door Gehakt op 16-01-2007 12:26 ]


Acties:
  • 0 Henk 'm!

  • igmar
  • Registratie: April 2000
  • Laatst online: 03-09 22:58

igmar

ISO20022

Je moet dan extern char xxx[3]; in jouw geval opgeven. Anders weet de compiler niet hoe lang de array is. een extern char * xxx; zou ook moeten werken.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

igmar schreef op dinsdag 16 januari 2007 @ 12:24:
Je moet dan extern char xxx[3]; in jouw geval opgeven. Anders weet de compiler niet hoe lang de array is.
Hoeft ie niet te weten zolang je geen sizeof nodig hebt. extern char strA[]; werkt dus prima.
een extern char * xxx; zou ook moeten werken.
Maar dan declareer je een pointer naar char, wat iets anders is dan een array van char.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • igmar
  • Registratie: April 2000
  • Laatst online: 03-09 22:58

igmar

ISO20022

.oisyn schreef op dinsdag 16 januari 2007 @ 12:50:
Hoeft ie niet te weten zolang je geen sizeof nodig hebt. extern char strA[]; werkt dus prima.
Ik kreeg d'r wel een warning op.
Maar dan declareer je een pointer naar char, wat iets anders is dan een array van char.
Is het ook, maar voor een functieaanroep is een char[] equivalent aan een char *. Voor andere toepassingen mag het inderdaad niet nee, al wordt het wel veelvuldig (mis)bruikt.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

igmar schreef op dinsdag 16 januari 2007 @ 14:58:

Ik kreeg d'r wel een warning op.
Wat voor warning dan :?. Het is prima legale en goedgedefinieerde C.
Is het ook, maar voor een functieaanroep is een char[] equivalent aan een char *.
Alleen is dit geen functieaanroep maar een variabeledefinitie. Sterker nog, als test.c niet test.h include, en test.h declareert een char * strA terwijl test.c een char strA[] definieert, krijg je geen errors en compilet en linkt alles prima. Maar 't ontploft in je gezicht zodra je strA probeert te accessen vanuit main.c (als je mazzel hebt, 't kan net zo goed je hdd formatteren).

[ Voor 4% gewijzigd door .oisyn op 16-01-2007 15:06 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Prima legale goedgekeurde C mag nog steeds een warning opleveren. Unreachable code is zo'n standaard voorbeeld. Maar ik zou ook niet kunnen gokken wat hier het probleem is.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein

Pagina: 1