multiple definition, de miért?

 ( emberk | 2013. május 3., péntek - 15:05 )

Sziasztok.

Matematikával, és fizikával jól elvagyok, de vannak szakmai hiányosságaim C++-ban, így kérdezek. A probléma a következő. Adott egy nagyon teljesítmény igényes feladat, sok sok szálon:

Van egy pointerem, (ami egy sorvektor jelen esetben):
double *global_memo;
Ez egy 4 dimenziós tömb 1 dimenziós emulációban. Ebből másolok egy lokális tömböt, ezekben egyesével végrehajtom a függetleníthető részeket, majd összegzem, a global_memo-ba, és utána előlről az egészet (kvázi iteráció). Eddig ezek a közös változók egy hatalmas file-ben voltak definiálva, de kezdett a reszecskek.cpp-fájlom hatalmasra dagadni. gondoltam semmi gond. Írok egy headert, amibe beteszem a sok thread közös változóját, és szétszedem a filet. Lesz egy primer_elektron.cpp, szekunder_elektron.cpp plazma.cpp...... filem ahova szépen #include-val beteszem a kozos_valtozok.h-t, de erre multiple definition hiba üzenetet kapok. Nagy bajban nem vagyok, mert el vagyok egy giga-file-ben is (csak inhüvely gyulladást kapok a sok scrollozástól :) ), de egy include miért ad többszörös definíciót?

Előre is köszönöm a konstruktív válaszokat.

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

// kozos_valtozok.h

#ifndef KOZOS_VALTOZOK_H
#define KOZOS_VALTOZOK_H

// balblabla

#endif

így van.

------
3 fajta matematikus létezik. Aki tud számolni, és aki nem.

Nem értem pontosan; linkelni is akarsz .o fájlokat, vagy csak egy bináris készül?

A header guard-ot mindig minden .h-ra (.hpp-re) érdemes rátenni, de ez csak a probléma egy részét oldja meg.

Ha vannak globális változóid, és több modulban használod őket (több .o, majd összelinkeled), akkor a változók helyfoglalása az egyik .c-ben legyen, a .h-ban pedig extern deklarációként kell leírni, így a többi modulban nem él külön életet, mégis látszani fog.

+1 az extern -re.

Ugyanakkor hogyan is lesz .exe linkelés nélkül?

Az include -ot tekintsd úgy, mintha copy/paste -tel bemásolnád az include -olt fájlt a másikba a #include helyén.

De a többi file-ban a globális változók (ami nem a threadok része) nem panaszkodik a többszörös definíciókra, mert nem cask ez az egy header létezik.

------
3 fajta matematikus létezik. Aki tud számolni, és aki nem.

globalisak.cc:

double *global_memo;

globalisak.hh:

#ifndef GLOBALISAK_HH
#define GLOBALISAK_HH

extern double *global_memo;

#endif

hasznalja.cc:

#include "globalisak.hh"

g++ globalisak.cc hasznalja.cc -o programod

globalis valtozot probald meg azert elkerulni (nem, ne singletonnal)

--
NetBSD - Simplicity is prerequisite for reliability

továbbra is megvan a hiba.:
/home/ek/upp/_out/MyApps/Gun/GCC.Gui.Main.Mt.Shared.Sse2/tread_reszecskepalya.o:(.bss.global_memo+0x0): multiple definition of `global_memo'
------
3 fajta matematikus létezik. Aki tud számolni, és aki nem.

nem hiszem el! :)

objdump + grep osszes .o-ra mit mond?

--
NetBSD - Simplicity is prerequisite for reliability

objdump -Dslx *.o | grep memo > /home/ek/objd.txt

Nem szóltam bocsánat!!! Így megy rm *o után minden rendben.

Eredménye:

6 .bss.global_memo 00000008 0000000000000000 0000000000000000 000001c0 2**3
0000000000000000 l d .bss.global_memo 0000000000000000 .bss.global_memo
0000000000000000 g O .bss.global_memo 0000000000000008 global_memo
Disassembly of section .bss.global_memo:
0000000000000000 :
310 .text.startup._GLOBAL__sub_I_global_memo 0000009b 0000000000000000 0000000000000000 00006dba 2**0
319 .bss.global_memo 00000008 0000000000000000 0000000000000000 00007120 2**3
0000000000000000 l d .text.startup._GLOBAL__sub_I_global_memo 0000000000000000 .text.startup._GLOBAL__sub_I_global_memo
0000000000000000 l F .text.startup._GLOBAL__sub_I_global_memo 000000000000009b _GLOBAL__sub_I_global_memo
0000000000000000 l d .bss.global_memo 0000000000000000 .bss.global_memo
0000000000000000 g O .bss.global_memo 0000000000000008 global_memo
Contents of section .text.startup._GLOBAL__sub_I_global_memo:
d2: R_X86_64_PC32 global_memo+0xfffffffffffffffc
190: R_X86_64_PC32 global_memo+0xfffffffffffffffc
2cc: R_X86_64_PC32 global_memo+0xfffffffffffffffc
b9: R_X86_64_PC32 global_memo+0xfffffffffffffffc
177: R_X86_64_PC32 global_memo+0xfffffffffffffffc
2b8: R_X86_64_PC32 global_memo+0xfffffffffffffffc
3: R_X86_64_PC32 global_memo+0xfffffffffffffffc
3: R_X86_64_PC32 global_memo+0xfffffffffffffffc
3: R_X86_64_PC32 global_memo+0xfffffffffffffffc
99: R_X86_64_PC32 global_memo+0xfffffffffffffffc
19f: R_X86_64_PC32 global_memo+0xfffffffffffffffc
40f: R_X86_64_PC32 global_memo+0xfffffffffffffffc
4a: R_X86_64_PC32 global_memo+0xfffffffffffffffc
49: R_X86_64_PC32 global_memo+0xfffffffffffffffc
70: R_X86_64_PC32 global_memo+0xfffffffffffffffc
85: R_X86_64_PC32 global_memo+0xfffffffffffffffc
a5: R_X86_64_PC32 global_memo+0xfffffffffffffffc
Disassembly of section .text.startup._GLOBAL__sub_I_global_memo:
0000000000000000 <_GLOBAL__sub_I_global_memo>:
_GLOBAL__sub_I_global_memo():
10: 48 c7 05 00 00 00 00 movq $0x0,0x0(%rip) # 1b <_GLOBAL__sub_I_global_memo+0x1b>
1b: c7 05 00 00 00 00 00 movl $0x0,0x0(%rip) # 25 <_GLOBAL__sub_I_global_memo+0x25>
25: c7 05 00 00 00 00 00 movl $0x0,0x0(%rip) # 2f <_GLOBAL__sub_I_global_memo+0x2f>
2f: e8 00 00 00 00 callq 34 <_GLOBAL__sub_I_global_memo+0x34>
43: 48 c7 05 00 00 00 00 movq $0x0,0x0(%rip) # 4e <_GLOBAL__sub_I_global_memo+0x4e>
4e: c7 05 00 00 00 00 00 movl $0x0,0x0(%rip) # 58 <_GLOBAL__sub_I_global_memo+0x58>
58: c7 05 00 00 00 00 00 movl $0x0,0x0(%rip) # 62 <_GLOBAL__sub_I_global_memo+0x62>
62: e8 00 00 00 00 callq 67 <_GLOBAL__sub_I_global_memo+0x67>
67: 48 c7 05 00 00 00 00 movq $0x0,0x0(%rip) # 72 <_GLOBAL__sub_I_global_memo+0x72>
72: c7 05 00 00 00 00 00 movl $0x0,0x0(%rip) # 7c <_GLOBAL__sub_I_global_memo+0x7c>
81: c7 05 00 00 00 00 00 movl $0x0,0x0(%rip) # 8b <_GLOBAL__sub_I_global_memo+0x8b>
0: R_X86_64_64 .text.startup._GLOBAL__sub_I_global_memo
Disassembly of section .bss.global_memo:
0000000000000000 :
1224: R_X86_64_PC32 .text.startup._GLOBAL__sub_I_global_memo

------
3 fajta matematikus létezik. Aki tud számolni, és aki nem.

na azert :p

--
NetBSD - Simplicity is prerequisite for reliability

> Így megy rm *o után minden rendben.

kovetkezo pont: dependency kezeles!

A'rpi