[C++] fatal error LNK1169: multiply defined symbols

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Rygir
  • Registratie: Mei 2004
  • Laatst online: 01-03 05:45
Ik krijg dus de foutfatal error LNK1169: one or more multiply defined symbols found C:\Documents and Settings\Eerste gebruiker\Bureaublad\UHasselt TMP\TMP TMS\TMS Video Compression\Video Compression trunk\Debug\VideoCodec.exe
.

Nu heb ik die natuurlijk al eerder gehad en opgezocht en weet ik dat dat is wat je krijgt als je hetzelfde ding meerdere keren definieert...

Alleen snap ik niet hoe dat nu kan in mijn geval :
  • Ik include alleen files met #pragma once (wat Visual Studio zelf genereert) of
    C++: filename.ext
    1
    2
    3
    4
    
    #ifndef FILENAME_EXT 
    #define FILENAME_EXT
    [i]<code>[/i]
    #endif
  • Alles werkt, zolang ik die header file maar niet include in 2 verschillende cpp files.
Het zit dus zo, ik heb 4 bestanden.
- de probleemfile, a.h. Deze bevat 1 functie in een namespace (voor het voorbeeld tenminste).
- main.cpp, waar het programma start en waar ik die functie nodig heb.
- bla.h en bla.cpp waarin ik een class definieer en die gebruikt de functie uit de probleem file ook.

In main.cpp wordt de probleemfile dus geinclude en naar keuze in bla.h of bla.cpp. Beide mogelijkheden resulteren in de genoemde error.

Kennelijk is dit niet de juiste aanpak...

Hoe moet ik nu wel correct iets maken als de STL library, een simpele file die je kan includen met een handvol nuttige functies, afgeschermd in hun eigen namespace? Ik wil die namelijk niet in een speciaal object moeten gaan moffelen en dan allemaal static zitten maken want dat is ook maar overdreven lijkt mij. Plus, als de STL library het kan, waarom ik dan niet?





En dan nu maar even de voorbeeld code :
C++: a.h
1
2
3
4
5
6
7
8
#ifndef A_H
#define A_H

namespace blala
{
        void func(){}
}
#endif


C++: main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <algorithm>
#include <string>
#include <iostream>
#include <cctype> // for toupper()

#include "cube.h"
#include "a.h"

int main()
{
        std::string s("hello"); // lowercase
        // transform the string to uppercase
        std::transform(s.begin(), // original string's beginning
                s.end(), // original string's end
                s.begin(), // where to write the new string?
                toupper); // unary operator

        std::cout << s; // display "HELLO"


/*begin http://www.functionx.com/cpp/examples/simpleclass.htm*/
        Cube cube;      
        cube.setSide(-12.55);
        cube.Properties();      
        Cube de;
        de.setSide(28.15);      
        de.Properties();
/*einde  http://www.functionx.com/cpp/examples/simpleclass.htm*/

        blala::func();

        system("pause");
}


C++: bla.h
1
2
3
4
5
6
7
8
9
#pragma once
#include "a.h"
class bla
{
public:
        bla(void);
public:
        ~bla(void);
};


C++: bla.cpp
1
2
3
4
5
6
7
8
9
10
#include "bla.h"


bla::bla(void)
{
}

bla::~bla(void)
{
}


Wat ik ook al heb geprobeerd is :
C++: a.h
1
2
3
4
5
6
7
8
#ifndef A_H
#define A_H

namespace blala
{
        void func();
}
#endif

met tegelijk
C++: a.cpp
1
2
3
4
5
6
7
8
9
#include "a.h"

#include <iostream>
namespace blala
{
        void func()
        {std::cout<<"functie in namespees"; }
}
#endif



Dan kreeg ik de error
fatal error LNK1120: 1 unresolved externals C:\Documents and Settings\Eerste gebruiker\Mijn documenten\Visual Studio 2005\Projects\Testproject\Debug\Testproj.exe



Als ik in main.cpp blala::func(); in commentaar zet, dan compileert het wel, maar is het vrij nutteloos natuurlijk (tenminste, met de cpp en .h aanpak van hier beneden - met de aanpak van boven met enkel de .h, dan krijg ik dezelfde multiply defined fout).

Het komt er op neer dat als ik't include op 2 plaatsen inclusief functie definitie, dan krijg ik die multiply defines, ongeacht dat er include guards rond staan. Als ik 't opsplits in .h en .cpp file zoals een class (maar het is een namespace, en ik heb dat echt NERGENS zo zien doen in geen enkel voorbeeld), dan mag ik de functie niet gebruiken want dan klaagt hij dat ze niet bestaat.

Ik kan trouwens ook vermelden dat ik heb geprobeerd om het probleem bestand a.cpp te noemen ipv a.h en dat te includen, en dat geeft nog veel gemakkelijker die error... ben de situatie even kwijt, maar komt er op neer dat als je die include ergens dan is het al fout want dan vind hij de definities al in die a.obj en de obj die hij gemaakt heeft van je file waar je het include. Hij is dan blijkbaar in conflict met zichzelf (ligt het nu aan mij of mocht C(++) qua syntax wel wat intelligenter zijn? Zo'n dingen moet je toch automatisch kunnen oplossen zonder te kijken naar bestandsextensies).



Dus de vraag in het kort is : Wat is de correcte aanpak voor een "algemene library" te schrijven met wat losse functies zoals de STL?

En in het concreet, hoe kan je multiply defines fout krijgen zelfs als je files include guards en/of pragma once bevatten?

[ Voor 6% gewijzigd door Rygir op 16-08-2009 06:22 . Reden: a.cpp aanpak ook nog even vermelden. ]


Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

probeer eens
extern void func();

STL is bijna volledig inline gedefinieerd.
Het is trouwens geen lib met losse functies ;)

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22:35
Dit:

C++:
1
2
3
4
namespace blala
{
        void func(){}
} 


is een functiedefinitie. Je zult em dus moeten declareren als extern en de accolades weghalen, of declareren als inline en de goede definitie in je header zetten.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Rygir
  • Registratie: Mei 2004
  • Laatst online: 01-03 05:45
H!GHGuY schreef op zondag 16 augustus 2009 @ 08:11:
probeer eens
extern void func();

STL is bijna volledig inline gedefinieerd.
Het is trouwens geen lib met losse functies ;)
ik denk zo aan dingen als cout (niet echt een geweldig voorbeeld vermits dat wschl wel een object is) en atoi() en printf() ... die zijn beschikbaar mits includes en juiste namespace, je maakt daar geen objecten van aan en je moet ook niet klasse::static functie aanroepen, als je begrijpt wat ik bedoel.

Uiteraard zit in STL ook een heleboel spul gelijk vectoren en lijsten, die objecten negeer ik even voor het gemak - als dat is wat je bedoelde met "het is geen lib met losse functies"...


Maar to the point : waarom moeten die extern zijn? Als ik dat goed begrijp dient dat toch om iets global te maken?


En ik heb eigenlijk het aan de praat gekregen... blijkbaar had ik met dat .cpp en .h naamsveranderen ook de .cpp file op "exclude from build" gezet, waardoor ik die foutmelding kreeg. Nu werkt het dus wel, zoals ik had voorgesteld, opgesplits over een .h en .cpp file.

Blijf ik dus met de vraag zitten of het wel de bedoeling is om namespaces over .h en .cpp files te splitsen?

Acties:
  • 0 Henk 'm!

  • Rygir
  • Registratie: Mei 2004
  • Laatst online: 01-03 05:45
farlane schreef op zondag 16 augustus 2009 @ 09:23:
Dit:

C++:
1
2
3
4
namespace blala
{
        void func(){}
} 


is een functiedefinitie. Je zult em dus moeten declareren als extern en de accolades weghalen, of declareren als inline en de goede definitie in je header zetten.
Niet tegendraads bedoeld, maar waarom? Als ik iets include, dan is dat toch equivalent met het cut'n pasten van die hele blok code daar?
Als ik daar een functie los zwevend zou schrijven, dan werkt dat gewoon. Dus waarom werkt dat niet meer met een namespace er rond?

(daar=waar ook de main functie staat).

En naar wat ik geleerd heb is inline weinig meer dan een suggestie voor de compilers tegenwoordig (ze doen het automatisch en negeren het soms ook als je het vraagt)? Dat dient toch om in plaats van een functie aanroep gewoon de hele functie daar ineens te plakken, voor overhead van function calls weg te halen bij hele hele korte functies? Hoe kan dat helpen?


Plus wat ik echt onmogelijk blijf vinden is hoe het kan dat die TOCH iets 2 keer doet, terwijl de preprocessor dat zou hebben moeten verhinderd dmv pragma once/guards.

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22:35
Rygir schreef op zondag 16 augustus 2009 @ 10:07:
Maar to the point : waarom moeten die extern zijn? Als ik dat goed begrijp dient dat toch om iets global te maken?
Met extern delareer je een item, maar zeg je dat de definitie ergens anders staat. Default is dit overigens voor functiesdeclaraties al het geval.
En ik heb eigenlijk het aan de praat gekregen... blijkbaar had ik met dat .cpp en .h naamsveranderen ook de .cpp file op "exclude from build" gezet, waardoor ik die foutmelding kreeg. Nu werkt het dus wel, zoals ik had voorgesteld, opgesplits over een .h en .cpp file.
Ik zie niet in hoe dat je fout kan veroorzaken/oplossen eigenlijk. Je hebt meerdere definities van een functie en door een unit toe te voegen wordt dat opgelost? Leg eens uit hoe dat werkt.
Blijf ik dus met de vraag zitten of het wel de bedoeling is om namespaces over .h en .cpp files te splitsen?
Ja, dat is zeer gebruikelijk. Namespaces zijn in dat opzicht ook "open", je kunt vanuit meerdere units declaraties/definities in eenzelfde namespace zetten.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Rygir
  • Registratie: Mei 2004
  • Laatst online: 01-03 05:45
farlane schreef op zondag 16 augustus 2009 @ 10:18:
[...]

Met extern delareer je een item, maar zeg je dat de definitie ergens anders staat. Default is dit overigens voor functiesdeclaraties al het geval.
Dusss...
C++:
1
void func();
is equivalent met
C++:
1
 extern void func();
?
[...]

Ik zie niet in hoe dat je fout kan veroorzaken/oplossen eigenlijk. Je hebt meerdere definities van een functie en door een unit toe te voegen wordt dat opgelost? Leg eens uit hoe dat werkt.
De code was opgesplitst over een .h file (met functie prototypes zoals
C++:
1
void func();
en een .cpp file met de implementaties daarvan. De .cpp file werd niet geinclude in de build, dus vrij logisch dat hij dan zegt dat hij unresolved externals heeft. Eenmaal die wel geinclude wordt in de build maakt hij daar z'n obj file van en heeft de linker iets om te linken.

... en het valt me nu pas op dat error het over externals heeft, zo te zien zijn functie prototypes echt wel hetzelfde als dat extern keyword...?
[...]


Ja, dat is zeer gebruikelijk. Namespaces zijn in dat opzicht ook "open", je kunt vanuit meerdere units declaraties/definities in eenzelfde namespace zetten.
Ja dat namespace extenden had ik ook al bekeken, daarmee dat ik op het idee was gekomen om het te splitsen. In principe zou je dus de std namespace kunnen uitbreiden (maar dat lijkt me sterk af te raden natuurlijk - ik neem het maar als illustratie van hoe een namespace in code waar je niets aan te zeggen hebt uitbreidbaar is).

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22:35
Rygir schreef op zondag 16 augustus 2009 @ 10:14:
Niet tegendraads bedoeld, maar waarom? Als ik iets include, dan is dat toch equivalent met het cut'n pasten van die hele blok code daar?
Als ik daar een functie los zwevend zou schrijven, dan werkt dat gewoon. Dus waarom werkt dat niet meer met een namespace er rond?

(daar=waar ook de main functie staat).
Dit is een definitie omdat je accolades plaatst achter je functiedeclaratie. Je zoekt de fout in het namespace gedoe maar dat is niet de oorzaak.
En naar wat ik geleerd heb is inline weinig meer dan een suggestie voor de compilers tegenwoordig (ze doen het automatisch en negeren het soms ook als je het vraagt)? Dat dient toch om in plaats van een functie aanroep gewoon de hele functie daar ineens te plakken, voor overhead van function calls weg te halen bij hele hele korte functies? Hoe kan dat helpen?
Ze hebben je alleen niet het hele verhaal verteld. Kijk eens naar Wikipedia: One Definition Rule
Plus wat ik echt onmogelijk blijf vinden is hoe het kan dat die TOCH iets 2 keer doet, terwijl de preprocessor dat zou hebben moeten verhinderd dmv pragma once/guards.
Omdat dat alleen werkt als je vanuit dezelfde translation unit meerdere keren een bepaalde header include. Dus bv A.cpp include A.h, die B.h include die vervolgens weer A.h include.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22:35
Rygir schreef op zondag 16 augustus 2009 @ 10:30:
Dusss...
C++:
1
void func();
is equivalent met
C++:
1
 extern void func();
?
Inderdaad.
De code was opgesplitst over een .h file (met functie prototypes zoals
C++:
1
void func();
en een .cpp file met de implementaties daarvan. De .cpp file werd niet geinclude in de build, dus vrij logisch dat hij dan zegt dat hij unresolved externals heeft. Eenmaal die wel geinclude wordt in de build maakt hij daar z'n obj file van en heeft de linker iets om te linken.

... en het valt me nu pas op dat error het over externals heeft, zo te zien zijn functie prototypes echt wel hetzelfde als dat extern keyword...?
Je kreeg "one or more multiply defined symbols", niet "unresolved externals".

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

Rygir schreef op zondag 16 augustus 2009 @ 10:07:
ik denk zo aan dingen als cout (niet echt een geweldig voorbeeld vermits dat wschl wel een object is)
Is idd een object.
en atoi()
Is een deel van de standard library, maar is GEEN STL.
en printf() ...
idem
die zijn beschikbaar mits includes en juiste namespace, je maakt daar geen objecten van aan en je moet ook niet klasse::static functie aanroepen, als je begrijpt wat ik bedoel.
Open eens de iostream file van jou compiler en zoek eens de definitie van cout:
Voor VS 2009 is dit:
C++:
1
extern ostream &cout;

Het is dus gewoon een global gedefinieerd object.
Uiteraard zit in STL ook een heleboel spul gelijk vectoren en lijsten, die objecten negeer ik even voor het gemak - als dat is wat je bedoelde met "het is geen lib met losse functies"...
En dat is net wat STL WEL is. Neem maar even _de_ referentie door van STL:
http://www.sgi.com/tech/stl/
Maar to the point : waarom moeten die extern zijn? Als ik dat goed begrijp dient dat toch om iets global te maken?
Binnen C++ werk je eigenlijk met compilatie-units.
Grof gezegd is elke CPP-file die je compileert een zo'n compilatie-unit. Hierbinnen worden alle #include directives vervangen door de effectieve contents van de file. Elke compilatie-unit wordt hierna gecompileerd naar een object-file.
Daarna worden alle object-files samengevoegd door de linker.
Als je nu in een headerfile "blaat.h"
code:
1
2
3
4
void function()
{
  std::cout << "blaat" << std::endl;
}

definieert (niet declareert!) dan heeft elke compilatie-unit die blaat.h include een functie "function".
Wanneer de linker dan die object-files moet samenvoegen ziet hij meerdere definities voor function() en weet hij niet welke nu degene is die uiteindelijk in de executable moet komen.
Oplossingen zijn:
- inline declareren. Inline functies worden ofwel geinlined ofwel als "weak" symbol aanzien. De linker zal bij meerdere weak symbols er 1 van nemen en die gebruiken.
- extern definieren en in een CPP-file definieren. De extern zal aanduiden dat een functie in een andere compilatie-unit aanwezig is tijdens compilatie (~ "compiler: shut up") en de linker zal weten dat alle extern's pointen naar die ene definitie van function()
Blijf ik dus met de vraag zitten of het wel de bedoeling is om namespaces over .h en .cpp files te splitsen?
namespaces kunnen per definite geheropend worden. Hun grote doel is de mogelijkheid geven om niet de globale namespace te vervuilen en om dan ook naam-conflicten te voorkomen.
Het is een logische samenbinding van namen. Dingen die logisch samenhoren in dezelfde namespace kunnen dus, onafhankelijk van hun plaats, in dezelfde namespace.

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

  • Rygir
  • Registratie: Mei 2004
  • Laatst online: 01-03 05:45
farlane schreef op zondag 16 augustus 2009 @ 10:41:
Je kreeg "one or more multiply defined symbols", niet "unresolved externals".
Jawel hoor, ik kreeg unresolved externals. Als ik geen symbols define, alleen maar declareer kan ik ze moeiljk multiple keer definen he :)

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22:35
Rygir schreef op zondag 16 augustus 2009 @ 14:43:
[...]

Jawel hoor, ik kreeg unresolved externals. Als ik geen symbols define, alleen maar declareer kan ik ze moeiljk multiple keer definen he :)
Mja zal wel, ik ga even af op je topictitel. Iig, deze code:
C++:
1
2
3
4
5
6
7
8
#ifndef A_H
#define A_H

namespace blala
{
        void func(){}
}
#endif


Declareert en definieert een functie func, in dit geval in een namespace. Ook al zou je die namespace weghalen, dan nog zou je bij gebruik vanuit verschillende translation units ( cpp files ) de fout krijgen die je in je topictitel hebt staan. Onafhankelijk of je de functie wel of niet in een namespace zet.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 00:27

.oisyn

Moderator Devschuur®

Demotivational Speaker

Rygir schreef op zondag 16 augustus 2009 @ 10:30:
In principe zou je dus de std namespace kunnen uitbreiden (maar dat lijkt me sterk af te raden natuurlijk [..]).
Nee. Een std::swap() overload voor je eigen type is typisch iets waarvoor je de std namespace uitbreidt :)

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!

  • Rygir
  • Registratie: Mei 2004
  • Laatst online: 01-03 05:45
farlane schreef op zondag 16 augustus 2009 @ 10:38:
Dit is een definitie omdat je accolades plaatst achter je functiedeclaratie. Je zoekt de fout in het namespace gedoe maar dat is niet de oorzaak.
Het probleem was dat bij het includen die include guards alleen maar invloed hebben binnen een translation unit, en dat als die daarna gelinked worden er alsnog duplicaten zijn omdat er verschil is tussen source en header files, iets wat ik nooit ergens heb gelezen in de cursus en wat me eigenlijk vrij basiskennis lijkt. Daar ik ook het verschil ken tussen een declaratie en een definitie had ik bewust gekozen om ze te zetten waar ze stonden, dus dat moest zo blijven totdat ik wist wat er precies mis ging, en nu ik dat weet is het ook in orde, en netjes gesplitst. En sorry voor de indruk te geven dat de namespace de oorzaak was, dat was misschien verkeerd verwoord.
Ze hebben je alleen niet het hele verhaal verteld. Kijk eens naar Wikipedia: One Definition Rule
Omdat dat alleen werkt als je vanuit dezelfde translation unit meerdere keren een bepaalde header include. Dus bv A.cpp include A.h, die B.h include die vervolgens weer A.h include.
Ja nu ik het belang van die translation units snap begrijp ik ook waarom inline zo'n grote invloed heeft; eenmaal ingevoegd zijn ze in zekere zin naamloos geworden en kunnen ze niet meer in conflict raken bij het linken. Vergelijkbaar met als je een paar regels code als preprocessor statement her en der invoegt, alleen een stap later (Die One Definition Rule pagina vond ik overigens niet erg veel zeggen, de regels die daar staan zijn erg voor de hand liggend, naar mijn bescheiden mening).

En je voorbeeld helderde ook het nut van de include guards op (zie ook andere topic).
farlane schreef op zondag 16 augustus 2009 @ 15:02:
Declareert en definieert een functie func, in dit geval in een namespace. Ook al zou je die namespace weghalen, dan nog zou je bij gebruik vanuit verschillende translation units ( cpp files ) de fout krijgen die je in je topictitel hebt staan.
De oplossing is dus gewoon zo :
C++:
1
2
3
4
5
6
7
8
#ifndef A_H
#define A_H

namespace blala
{
        inline void func(){}
}
#endif


waarbij ik eigenlijk ook beter mijn bedoeling uitdruk; simpele functies die her en der bruikbaar zijn en geen klasse waardig.
.oisyn schreef op zondag 16 augustus 2009 @ 18:13:
Nee. Een std::swap() overload voor je eigen type is typisch iets waarvoor je de std namespace uitbreidt :)
Hehe :) . Dat is een goed voorbeeld... ik meen me thans te herinneren dat op de C++ faq site werd ontraden om iets in de std namespace te doen, maar ze hadden het waarschijnlijk meer over dingen bijmaken.

Dat klinkt in ieder geval wel alsof je een prima voorbeeld hebt van een "losse functie" zoals ik ze bedoelde in mijn TS, een functie die geen member functie is, waar je dus geen class voor moet maken en die toch in een namespace zit.

Voor bijvoorbeeld atoi() enzo las ik dat afhankelijk van of je de <something.h> of de <csomething> header include die enkel in de std namespace of ook in de global namespace beschikbaar waren, voor backwards C compatability (come to think of it, in C zijn toch ook namespaces? waarom hebben ze die daar toen niet ingestoken?). (Ik heb niet nagekeken of dat nu voor de atoi() functie gold) Als je die wilt overloaden, doe je dat dan zo :
C++:
1
2
3
4
namespace std{
 (inline) juiste_type bestaande_functie_naam(){} /*of met declaratie en dan elders definiëren afhankelijk van wat het precies is en hoe het origineel is gemaakt... */
}
(inline)  juiste_type bestaande_functie_naam(){} 

Met andere woorden : 2 keer knal hetzelfde definiëren (of doorverwijzen naar 1 van de twee implementaties natuurlijk). Of is er een alias die zegt dat std, met die headers, gelijk is aan de global namespace, al dan niet voor specifieke functies (daar heb ik dan nog nooit van gehoord, dat je een alias zou kunnen maken voor delen van een namespace).

Ik moet ook nodig eens opzoeken waarom sommige met brackets er rond en sommige met aanhalingstekens geïnclude worden....

Als je iets overload waarvan het origineel "inline" is, of net niet, en je doet nu het tegenovergestelde (al dan niet inline dus)... mag dat? Kan me voorstellen dat dat lastig is voor de compiler omdat onder sommige omstandigheden het een weak symbol is en andere omstandigheden ineens niet...

[ Voor 43% gewijzigd door Rygir op 19-08-2009 01:26 . Reden: aanvullen om niet te veel berichtjes te moeten maken :) ]


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22:35
Rygir schreef op woensdag 19 augustus 2009 @ 00:07:
Het probleem was dat bij het includen die include guards alleen maar invloed hebben binnen een translation unit, en dat als die daarna gelinked worden er alsnog duplicaten zijn omdat er verschil is tussen source en header files, iets wat ik nooit ergens heb gelezen in de cursus en wat me eigenlijk vrij basiskennis lijkt.
Het is eigenlijk het build proces wat te weinig aan de orde komt, maar wat wel bij de basis hoort.

Trouwens, het hele header/source verhaal is meer een ongeschreven wet; het is niet iets wat door de C++ standaard wordt voorgeschreven oid. C++ an sich maakt geen verschil tussen .h of .cpp bestanden, het is afhakelijk van de compilerbouwer hoe die extensies worden gebruikt ( gelukkig wel redelijk uniform )

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Rygir
  • Registratie: Mei 2004
  • Laatst online: 01-03 05:45
farlane schreef op woensdag 19 augustus 2009 @ 00:20:
Het is eigenlijk het build proces wat te weinig aan de orde komt, maar wat wel bij de basis hoort.
Dat is een vak apart geworden :) (letterlijk; we kunnen een vak volgen waarin ze make scripts enzo maken, maar dat hoorde niet bij mijn lessenpakket. Misschien als ik tijd vind dat ik' t voor de lol eens ga volgen).
Trouwens, het hele header/source verhaal is meer een ongeschreven wet; het is niet iets wat door de C++ standaard wordt voorgeschreven oid. C++ an sich maakt geen verschil tussen .h of .cpp bestanden, het is afhakelijk van de compilerbouwer hoe die extensies worden gebruikt ( gelukkig wel redelijk uniform )
Nee, ja, zoals in de andere thread al vermeld zijn de extensies niet van belang. Wat wel van tel is is dat "sommige" source files anders behandeld worden als andere, en door de compiler gesmeten worden, terwijl andere losjes worden opgevraagd op andere wijze (de headers).

Het is naar't schijnt zelfs de IDE en niet zozeer de compiler die let op de extensies en bepaald hoe er mee wordt omgegaan.
Pagina: 1