Toon posts:

[c++ standard] extern const

Pagina: 1
Acties:

Verwijderd

Topicstarter
Voor de guru's... (althans, ik kon het niet terug vinden in mijn textbook)

Stel je define een array en met c++ kan dat op verschillende manieren:


Globaal (dus ook buiten compilation unit zichtbaar):
C:
1
2
3
unsigned char somearray[]={
  .....
  };



Local (alleen zichtbaar vanuit compilation unit):
C:
1
2
3
static unsigned char somearray[]={
  .....
  };



Stel nu dat we hem const maken:
C:
1
2
3
const unsigned char somearray[]={
  .....
  };

Dan blijkt dat de array eigenlijk local is (alleen zichtbaar vanuit compilation unit)

Om een hem global (dus ook buiten compilation unit zichtbaar) te maken, moeten we gebruik maken van extern:
C:
1
2
3
extern const unsigned char somearray[]={
  .....
  };


Waarom is dat precies zo gedaan? waarom is "const unsigned char" niet gewoon global en "static const unsigned char" niet gewoon local. Waarom deze uitzondering dmv extern?

Alvast bedankt _/-\o_

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Volgens mij ben je een paar dingen een beetje door de war aan het halen. Mag ik vragen welke van bovenstaande definities je zoal in de header- of in de sourcefile wilde zetten? :)

Professionele website nodig?


Verwijderd

Topicstarter
curry684 schreef op 03 augustus 2004 @ 23:51:
Volgens mij ben je een paar dingen een beetje door de war aan het halen. Mag ik vragen welke van bovenstaande definities je zoal in de header- of in de sourcefile wilde zetten? :)
Deze staan allemaal in de source file :*)

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Verwijderd schreef op 04 augustus 2004 @ 00:01:
[...]

Deze staan allemaal in de source file :*)
Wat doet die extern-declaratie daar dan? :) Die gebruik je om vanuit een sourcefile te refereren aan een variabele met external linkage in een ander object ;)

Professionele website nodig?


Verwijderd

Topicstarter
curry684 schreef op 04 augustus 2004 @ 00:05:
[...]

Wat doet die extern-declaratie daar dan? :) Die gebruik je om vanuit een sourcefile te refereren aan een variabele met external linkage in een ander object ;)
Ja... dat dacht ik ook, maar als ik vanuit een andere source file die const array wil gebruiken dan werkt dat dus niet behalve als ik hem als extern const defineer.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Verwijderd schreef op 04 augustus 2004 @ 00:13:
[...]


Ja... dat dacht ik ook, maar als ik vanuit een andere source file die const array wil gebruiken dan werkt dat dus niet behalve als ik hem als extern const defineer.
Dat klopt, maar dan moet je 'm niet nog een keer definieren zoals je hier nu doet :)

Je definieert een variabele maar eenmalig, en vervolgens moet je 'm in een andere sourcefile nog eens met extern declareren om hem te kunnen gebruiken :)

Professionele website nodig?


Verwijderd

Topicstarter
ah.... gevonden!!!!!!!!!!!!!! (in de c++ standard)


3 A name having namespace scope (_basic.scope.namespace_) has internal
linkage if it is the name of

--an object, reference, function or function template that is explic-
itly declared static or,

--an object or reference that is explicitly declared const and neither
explicitly declared extern nor previously declared to have external
linkage; or


--the name of a data member of an anonymous union.

Verwijderd

Topicstarter
curry684 schreef op 04 augustus 2004 @ 00:16:
[...]

Je definieert een variabele maar eenmalig, en vervolgens moet je 'm in een andere sourcefile nog eens met extern declareren om hem te kunnen gebruiken :)
Juist ja.... maar je moet hem dus ook extern defineren anders heb je internal linkage. zie mijn post hier boven...

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Dat is inderdaad omdat de compiler anders de 'const' wegoptimaliseert als ware het een C-style #define-macro, en dan is er dus geen fysieke storage om aan te refereren :)

Professionele website nodig?


Verwijderd

Topicstarter
curry684 schreef op 04 augustus 2004 @ 00:19:
Dat is inderdaad omdat de compiler anders de 'const' wegoptimaliseert als ware het een C-style #define-macro, en dan is er dus geen fysieke storage om aan te refereren :)
en nu weet ik ook waarom.... bedankt! :*)

  • AuC
  • Registratie: Januari 2003
  • Laatst online: 22-05 11:11

AuC

curry684 schreef op 04 augustus 2004 @ 00:16:
[...]

Dat klopt, maar dan moet je 'm niet nog een keer definieren zoals je hier nu doet :)

Je definieert een variabele maar eenmalig, en vervolgens moet je 'm in een andere sourcefile nog eens met extern declareren om hem te kunnen gebruiken :)
Of ik slaap nog half momenteel, of ik snap het niet helemaal, of ik doe het fout. Maar ik defineer altijd extern in een header file, en declareer gewoon in een source file. Dat is dus een verkeerde manier? Of haal ik declareren en defineren nou door de war?

in een header:
C++:
1
extern int iTestArray[5];


in een source file:
C++:
1
2
3
4
5
6
int iTestArray[5];

...

for( int i = 0; i < 5; i++ )
  iTestArray[i] = i;

Verwijderd

Hmmm, zo heb ik het tot nu toe ook altijd gedaan. Maar dit is toch correct?

Definiëren mag namelijk maar één keer (dus in sourcefile), en de declaratie moet voor alle gebruikende objecten zichtbaar zijn (dus in headerfile).

  • BoAC
  • Registratie: Februari 2003
  • Laatst online: 22-05 23:01

BoAC

Memento mori

AuC schreef op 04 augustus 2004 @ 08:28:
[...]


Of ik slaap nog half momenteel, of ik snap het niet helemaal, of ik doe het fout. Maar ik defineer altijd extern in een header file, en declareer gewoon in een source file. Dat is dus een verkeerde manier? Of haal ik declareren en defineren nou door de war?

in een header:
C++:
1
extern int iTestArray[5];
Je declareert dus eigenlijk dubbel ;)
Extern gebruik je in een source-file om een variable te declareren en te gebruiken zoal curry684 zegt en dan later te gebruiken.
In een header-file staan alleen maar declaraties.

  • AuC
  • Registratie: Januari 2003
  • Laatst online: 22-05 11:11

AuC

Aaah, ok....Ik snap het. Kijk, zo leer je nog eens wat. :)

  • mawashigeri
  • Registratie: November 2002
  • Laatst online: 22-05 11:59
Verwijderd schreef op 04 augustus 2004 @ 09:24:
Hmmm, zo heb ik het tot nu toe ook altijd gedaan. Maar dit is toch correct?
Inderdaad. Wel heb ik mijzelf aangeleerd gewoon overal specifiek te zijn en dus ook in de source de extern op te nemen. Deze kan geen kwaad en zorgt ervoor dat de variabelen/functies prettig uitlijnen. Nodig is het niet...

Er is wel 1 voordeel: als je een extern variabele in je source declareerd maar niet initialiseerd dan krijg je een compiler error. Zoals je weet is het Goed om iedere variable te initialiseren :*) .

ERGA06EVH / EHVX08S23EJ6V / ESPaltherma


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

AuC schreef op 04 augustus 2004 @ 08:28:
[...]


Of ik slaap nog half momenteel, of ik snap het niet helemaal, of ik doe het fout. Maar ik defineer altijd extern in een header file, en declareer gewoon in een source file. Dat is dus een verkeerde manier? Of haal ik declareren en defineren nou door de war?
Ja :)

Declareren = roepen dat iets bestaat.
Definieren = uitschrijven hoe iets bestaat.

Professionele website nodig?


  • BoAC
  • Registratie: Februari 2003
  • Laatst online: 22-05 23:01

BoAC

Memento mori

curry684 schreef op 04 augustus 2004 @ 09:55:
[...]

Ja :)

Declareren = roepen dat iets bestaat.
Definieren = uitschrijven hoe iets bestaat.
Zou je dan ipv definieren niet beter kunnen zeggen implementeren?

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

de·cla·re·ren2 (wk.ww., zich ~)
1 zich over iets uitspreken

de·fi·ni·ë·ren (ov.ww.)
1 duidelijk omschrijven

im·ple·men·te·ren (ov.ww.)
1 (een plan) tot uitvoering brengen => verwezenlijken
2 [comp.] installeren, testen en in gebruik nemen van apparatuur, informatiesysteem, programmatuur en/of procedures => invoeren
;)

Implementeren doe je met functies die al lang en breed gedeclareerd en gedefinieerd zijn, zoals met pure virtual methods in een derived class.

Professionele website nodig?


  • AuC
  • Registratie: Januari 2003
  • Laatst online: 22-05 11:11

AuC

Ik probeer het eens...zet ik in global.h enkel dit:

C++:
1
2
3
4
5
6
#ifndef __GLOBAL_H_
#define __GLOBAL_H_

HWND g_hWnd;

#endif


en in main.cpp maak ik het scherm zo:

C++:
1
2
3
4
5
6
7
8
9
10
11
#include <windows.h>
#include "global.h"

int WINAPI WinMain( ... ) 
{
...

extern HWND g_hWnd = CreateWindowEx( ... );

...
}


Toch krijg ik dan een linker error:

code:
1
gdi.obj : error LNK2005: "struct HWND__ * g_hWnd" (?g_hWnd@@3PAUHWND__@@A) already defined in main.obj


Doe ik het nou op mijn "oude" manier, dan werkt het prima. 8)7

[ Voor 12% gewijzigd door AuC op 04-08-2004 11:21 ]


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 15:49

Creepy

Tactical Espionage Splatterer

AuC schreef op 04 augustus 2004 @ 11:19:
Ik probeer het eens...zet ik in global.h enkel dit:

Toch krijg ik dan een linker error:
...
Doe ik het nou op mijn "oude" manier, dan werkt het prima. 8)7
Die variabele is al gedeclareerd in je header file. En je declareert hem nog een keer in je c file.
C:
1
2
3
4
5
6
7
8
9
#include <windows.h>
#include "global.h"

int WINAPI WinMain( ... ) 
{
  // g_hWnd is gewoon rechtstreeks te gebruiken.
  // g_hWnd is al gedeclareerd in globals.h.
  g_hWnd = CreateWindowEx( ... );
}

Een #include is eigenlijk niks meer dan een domme vervang actie. Op de plaats van je #inlude komt de complete code van je header file. Dan zie je dus dat je twee keer
code:
1
HWND g_Hwnd;
hebt staan. En de compiler geeft je dus terecht een error.

[ Voor 64% gewijzigd door Creepy op 04-08-2004 11:28 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • AuC
  • Registratie: Januari 2003
  • Laatst online: 22-05 11:11

AuC

Dan krijg ik alsnog die linker error. De enige manier die ik kan vinden om die error niet te krijgen is door g_hWnd extern te declareren in global.h. :s

Edit op edit van Creepy:
Daarom vind ik het juist zo vreemd creepy.

[ Voor 20% gewijzigd door AuC op 04-08-2004 11:33 ]


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 15:49

Creepy

Tactical Espionage Splatterer

AuC schreef op 04 augustus 2004 @ 11:28:
Dan krijg ik alsnog die linker error. De enige manier die ik kan vinden om die error niet te krijgen is door g_hWnd extern te declareren in global.h. :s

Edit op edit van Creepy:
Daarom vind ik het juist zo vreemd creepy.
Welke linker error krijg je nu nog? De "already defined"?

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • AuC
  • Registratie: Januari 2003
  • Laatst online: 22-05 11:11

AuC

Creepy schreef op 04 augustus 2004 @ 11:34:
[...]

Welke linker error krijg je nu nog? De "already defined"?
Inderdaad.

Om precies te zijn heb ik nu in global.h dit staan:

C++:
1
2
3
4
5
6
7
8
9
10
#ifndef __GLOBAL_H_
#define __GLOBAL_H_

#include <windows.h>

HWND    g_hWnd;

void OnPaint( HDC hDC );

#endif


In zowel main.cpp als gdi.cpp (waar de functie OnPaint staat) include ik global.h. Ik amak het scherm nu zo:

C++:
1
g_hWnd = CreateWindowEx( ... );


En toch krijg ik nog de "already defined" error.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

AuC schreef op 04 augustus 2004 @ 11:28:
Dan krijg ik alsnog die linker error. De enige manier die ik kan vinden om die error niet te krijgen is door g_hWnd extern te declareren in global.h. :s.
Ja en dat is dus de hele bedoeling. Een include doet niets anders dan code binnentrekken, en als je dus in je header een 'int Pietje' definieert en die header in 5 sourcefiles include, bevatten alle 5 die sourcefiles de int Pietje!!! En dat gaat nogal fout ja met linken.

Je moet 'm dus in een enkele sourcefile definieren als 'int Pietje', en in de header als 'extern' declareren zodat de andere 4 sourcefiles weten dat de linker 'm ooit wel terug gaat vinden in de 5e!

Professionele website nodig?


  • AuC
  • Registratie: Januari 2003
  • Laatst online: 22-05 11:11

AuC

curry684 schreef op 04 augustus 2004 @ 11:38:
[...]

Ja en dat is dus de hele bedoeling. Een include doet niets anders dan code binnentrekken, en als je dus in je header een 'int Pietje' definieert en die header in 5 sourcefiles include, bevatten alle 5 die sourcefiles de int Pietje!!! En dat gaat nogal fout ja met linken.

Je moet 'm dus in een enkele sourcefile definieren als 'int Pietje', en in de header als 'extern' declareren zodat de andere 4 sourcefiles weten dat de linker 'm ooit wel terug gaat vinden in de 5e!
Dan begreep ik de vorige posts verkeerd :). Sorry.

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 15:49

Creepy

Tactical Espionage Splatterer

Als je sources files los van elkaar worden gecompileerd dan wordt zowel in je main.cpp en je gdi.cpp de g_hWnd vanuit de globals.h gedeclareerd. g_Hwnd zit dan in main.o en gdi.o. Tijdens het linken merkt de linker dat terecht op.

Maak een main.h waarin je de h_Hwnd declateert. Maak ook een gdi.h waarin je de OnPaint declareert. Mocht je de g_Hwnd variabele nodig hebben in gdi.cpp (wat ik betwijfel) declareer deze dan met extern in je gdi.h

Hint: misschien eens een goed boek over C kopen, of je leraar een schop geven dat hij dit de volgende keer wel goed uitlegt?

Edit: Wat Curry ook roept :z

[ Voor 3% gewijzigd door Creepy op 04-08-2004 11:42 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • BoAC
  • Registratie: Februari 2003
  • Laatst online: 22-05 23:01

BoAC

Memento mori

Creepy schreef op 04 augustus 2004 @ 11:41:
Als je sources files los van elkaar worden gecompileerd dan wordt zowel in je main.cpp en je gdi.cpp de g_hWnd vanuit de globals.h gedeclareerd. g_Hwnd zit dan in main.o en gdi.o. Tijdens het linken merkt de linker dat terecht op.

Maak een main.h waarin je de h_Hwnd declateert. Maak ook een gdi.h waarin je de OnPaint declareert. Mocht je de g_Hwnd variabele nodig hebben in gdi.cpp (wat ik betwijfel) declareer deze dan met extern in je gdi.h

Hint: misschien eens een goed boek over C kopen, of je leraar een schop geven dat hij dit de volgende keer wel goed uitlegt?

Edit: Wat Curry ook roept :z
En deze manier dan?
Volgens mij worden er 2 dingen doorelkaar gehaald of zie ik het verkeerd?
Voorbeeld:

test.h
C:
1
2
3
4
5
6
#ifndef __TEST_H_
#define __TEST_H_

int i;

#endif // __TEST_H_

test1.c
C:
1
2
3
4
5
6
7
8
#include "test.h"

int main(int argc, const char **argv)
{
    i = 5;

    foo();
}

test2.c
C:
1
2
3
4
5
6
#include "test.h"

void foo()
{
    printf("i = %d", i);
}


Niks geen problemen met already defined :?
Trouwens ook niet met de code van AuC
Waarom in main.cpp extern gebruiken voor de g_hWnd :?


Gebruik trouwen gnu c maar dat mag toch niet uitmaken?
Los of tegelijk compileren maakt ook niet uit ;)

[ Voor 7% gewijzigd door BoAC op 04-08-2004 12:32 ]


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 15:49

Creepy

Tactical Espionage Splatterer

code:
1
2
3
4
5
6
7
8
creepy@firewall:~/test$ make
g++    -c -o test1.o test1.c
g++    -c -o test2.o test2.c
g++ test1.o test2.o  -o test
test2.o(.bss+0x0): multiple definition of `i'
test1.o(.bss+0x0): first defined here
collect2: ld returned 1 exit status
make: *** [test] Error 1

Met los compileren gaat het dus wel mis. Overigens melpt gcc dan ook nog over het niet bestaan van foo() in test1.c aangezien foo() alleen in test2 is gedeclareerd.

Ik ben benieuwd hoe je dat los compileren hebt gedaan.

Edit: Hey, dat is maf. g++ geeft wel die error. Maar gcc (2.95.4) niet?

[ Voor 8% gewijzigd door Creepy op 04-08-2004 12:42 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • BoAC
  • Registratie: Februari 2003
  • Laatst online: 22-05 23:01

BoAC

Memento mori

Creepy schreef op 04 augustus 2004 @ 12:40:
code:
1
2
3
4
5
6
7
8
creepy@firewall:~/test$ make
g++    -c -o test1.o test1.c
g++    -c -o test2.o test2.c
g++ test1.o test2.o  -o test
test2.o(.bss+0x0): multiple definition of `i'
test1.o(.bss+0x0): first defined here
collect2: ld returned 1 exit status
make: *** [test] Error 1

Met los compileren gaat het dus wel mis. Overigens melpt gcc dan ook nog over het niet bestaan van foo() in test1.c aangezien foo() alleen in test2 is gedeclareerd.

Ik ben benieuwd hoe je dat los compileren hebt gedaan.

Edit: Hey, dat is maf. g++ geeft wel die error. Maar gcc (2.95.4) niet?
Ik gebruik 'gcc' ;) maar met g++ vraagt hij idd naar foo :?

[ Voor 5% gewijzigd door BoAC op 04-08-2004 12:45 ]


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 15:49

Creepy

Tactical Espionage Splatterer

BoAC schreef op 04 augustus 2004 @ 12:44:
[...]

Ik gebruik 'gcc' ;) maar met g++ vraagt hij idd naar foo :?
Opzich logisch. Je hebt foo nergens gedeclareerd, en bij het compileren van test1.c is foo dus nog niet bekend. Ik snap alleen niet waarom gcc dat niet oppakt (evenals de multiple definition van i).

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 11:06

Robtimus

me Robtimus no like you

Hoezo multiple definition van i? Daarvoor is die #ifndef #define #endif constructie in de header juist voor.

Verder:
[rspoor@dyn375 projects]$ gcc -Wall -c -o test1.o test1.c
test1.c: In function `main':
test1.c:7: warning: implicit declaration of function `foo'
test1.c:8: warning: control reaches end of non-void function
[rspoor@dyn375 projects]$ gcc -Wall -c -o test2.o test2.c
test2.c: In function `foo':
test2.c:5: warning: implicit declaration of function `printf'
[rspoor@dyn375 projects]$ gcc -Wall test1.o test2.o -o test
[rspoor@dyn375 projects]$
Warnings aanzetten en hij zeurt wel. Tijdens het linken vindt ie foo(), daarom gaat het goed.

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • BoAC
  • Registratie: Februari 2003
  • Laatst online: 22-05 23:01

BoAC

Memento mori

Het werk voor GNU C en GNU C++ dus zo ...

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

extern int i;

void foo();

#endif // __TEST_H_

test1.c
C:
1
2
3
4
5
6
7
8
9
10
#include "test.h"

int i; // <<----!!!

int main(int argc, const char **argv)
{
    i = 5;

    foo();
}

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

void foo()
{
    printf("i = %d", i);
}

Waarom C dus geen fout geeft begrijp ik nog niet 8)7
* BoAC heeft Stroustrup erbij gepakt en die vertelde hem dat extern wel moet worden gebruikt in Header-files ;)

[ Voor 8% gewijzigd door BoAC op 04-08-2004 13:04 ]


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 15:49

Creepy

Tactical Espionage Splatterer

IceManX schreef op 04 augustus 2004 @ 13:01:
Hoezo multiple definition van i? Daarvoor is die #ifndef #define #endif constructie in de header juist voor.

Verder:
[...]
Warnings aanzetten en hij zeurt wel. Tijdens het linken vindt ie foo(), daarom gaat het goed.
Met alles in 1 keer compileren lukt dat ja. Ga nu eens alle .c files los compileren m.b.v. een Makefile o.i.d. en je krijgt met g++ de foutmelding. Zie ook mijn compilatie slag. Elke .o file wordt los gecompileerd, en daarna pas wordt de boel aan elkaar gelinkt.
Je moet er toch niet aan denken dat als je 1 c file aanpast het gehele project elke keer opnieuw wordt gecompileerd (zeker niet bij erg grote projecten...)

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 15:49

Creepy

Tactical Espionage Splatterer

BoAC schreef op 04 augustus 2004 @ 13:02:
* BoAC heeft Stroustrup erbij gepakt en die vertelde hem dat extern wel moet worden gebruikt in Header-files ;)
Dan had de TS hier dus toch gelijk :)

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • BoAC
  • Registratie: Februari 2003
  • Laatst online: 22-05 23:01

BoAC

Memento mori

Creepy schreef op 04 augustus 2004 @ 13:06:
[...]

Dan had de TS hier dus toch gelijk :)
Voor C++: Ja ;)
Voor C: maybe ;) Geeft met -Wall ook geen warnings voor i ;)

Verwijderd

Topicstarter
IceManX schreef op 04 augustus 2004 @ 13:01:
Hoezo multiple definition van i? Daarvoor is die #ifndef #define #endif constructie in de header juist voor.
In geval van c++.

Nee, dat werkt alleen binnen 1 compilation unit dus bv door nesting van includes je per ongeluk 2x een header binnen slurpt.

Bij het linken krijg je nu een error omdat je 2 globale variabelen hebt gecreeerd met de zelfde naam. Of i static declareren, of extern in de header file gebruiken en i ergens in een van de source files zetten

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 11:06

Robtimus

me Robtimus no like you

Creepy schreef op 04 augustus 2004 @ 13:03:
[...]

Met alles in 1 keer compileren lukt dat ja. Ga nu eens alle .c files los compileren m.b.v. een Makefile o.i.d. en je krijgt met g++ de foutmelding. Zie ook mijn compilatie slag. Elke .o file wordt los gecompileerd, en daarna pas wordt de boel aan elkaar gelinkt.
Je moet er toch niet aan denken dat als je 1 c file aanpast het gehele project elke keer opnieuw wordt gecompileerd (zeker niet bij erg grote projecten...)
Ja klopt, ik merk het nu ook. Komt waarschijnlijk omdat ik geen variabelen in header files zet dat ik het nog nooit heb gemerkt. Met gcc krijg je waarschuwingen tijdens de compilatie van de object files, en tijdens linken komen er idd foutmeldingen dat i al gedefinieerd is.

vicz heeft ook gelijk; ik gebruik die constructie dus ook alleen voor structs, functies en typedefs.

More than meets the eye
There is no I in TEAM... but there is ME
system specs


Verwijderd

Topicstarter
Om nog even de situatie te schetsen die ik had (in 2 voorbeelden):

Eerste voorbeeld (zonder const):

test.h
C++:
1
extern int i;



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

int main(){

  printf("i=%d\n",i);

  return 1;
}



test2.cpp
C++:
1
int i=5;


Dit werkt allemaal perfect. Stel nu dat ik van die int een const int wil maken dan kan ik twee dingen doen. Zorgen dat ook test2.cpp #include "test.h" doet of ook gelijk extern const int neerzettnn. Ik had dus niet die test.h geinclude. Ofwel wat ik had gedaan was het volgende:


test.h
C++:
1
extern const int i;



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

int main(){

  printf("i=%d\n",i);

  return 1;
}



test2.cpp
C++:
1
2
3
4
// alleen te gebruiken als je extern weghaalt:
// #include "test.h"  

extern const int i=5;

  • BoAC
  • Registratie: Februari 2003
  • Laatst online: 22-05 23:01

BoAC

Memento mori

Maar dan moet je nog steeds i definieren in of test1.cpp of test2.cpp anders krijg je een unresolved externel.

Verwijderd

Topicstarter
BoAC schreef op 04 augustus 2004 @ 14:18:
Maar dan moet je nog steeds i definieren in of test1.cpp of test2.cpp anders krijg je een unresolved externel.
dat doe ik dus ook in test2.cpp :)

[ Voor 12% gewijzigd door Verwijderd op 04-08-2004 14:31 ]


  • BoAC
  • Registratie: Februari 2003
  • Laatst online: 22-05 23:01

BoAC

Memento mori

Verwijderd schreef op 04 augustus 2004 @ 14:23:
[...]
dat doe ik dus ook in test2.cpp :)
Je hebt gelijk ;)
Maar degene waar je de waarde aan toekent is de definitie, ongeacht of deze in de source of headerfile voorkomt :?

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 15:49

Creepy

Tactical Espionage Splatterer

BoAC schreef op 04 augustus 2004 @ 14:36:
[...]

Je hebt gelijk ;)
Maar degene waar je de waarde aan toekent is de definitie, ongeacht of deze in de source of headerfile voorkomt :?
code:
1
const int i = 5;

Definitie en declaratie in 1 :)

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • BoAC
  • Registratie: Februari 2003
  • Laatst online: 22-05 23:01

BoAC

Memento mori

Creepy schreef op 04 augustus 2004 @ 14:49:
[...]

code:
1
const int i = 5;

Definitie en declaratie in 1 :)
Maar TS wil in een source-file geen include doen :? (why?)
Zie [rml]vicz in "[ c++ standard] extern const"[/rml]

Volgens mij moet de TS het boek van Stroustrup maar es gaan doorlezen ;)
Zo wordt het volgens mij nodeloos ingewikkeld ;)

Verwijderd

Topicstarter
BoAC schreef op 04 augustus 2004 @ 14:36:
[...]

Je hebt gelijk ;)
Maar degene waar je de waarde aan toekent is de definitie, ongeacht of deze in de source of headerfile voorkomt :?
natuurlijk, maar meestal doe je dat niet in een header file sinds deze meestal door meerdere files worden gebruikt en je dus multiple definitions krijgt.

Verwijderd

Topicstarter
BoAC schreef op 04 augustus 2004 @ 14:54:
[...]

Maar TS wil in een source-file geen include doen :? (why?)
Zie [rml]vicz in "[ c++ standard] extern const"[/rml]
Toevallig wordt dit automatisch gegenereerd...
Volgens mij moet de TS het boek van Stroustrup maar es gaan doorlezen ;)
Zo wordt het volgens mij nodeloos ingewikkeld ;)
Wat is er dan ingewikkeld aan. Wordt er juist overzichtelijker op. Die hele header file hebben we niet eens nodig als we gewoon boven aan de source van test1.cpp dit neerzetten.

C++:
1
extern const int i;

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Waarom zijn const's impliciet static?
Omdat het niet uitmaakt hoeveel kopieen je hebt van const int VIJF = 5;
Je programma werkt hetzelfde ongeacht hoeveel objecten je hebt die VIJF heten, zolang ze allemaal maar 5 zijn.

C is anders, omdat C het concept kent van tentative declarations. Identieke definities worden als redeclaraties gezien. Dit is in C++ geschrapt.

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


  • BoAC
  • Registratie: Februari 2003
  • Laatst online: 22-05 23:01

BoAC

Memento mori

Verwijderd schreef op 04 augustus 2004 @ 14:58:
[...]
natuurlijk, maar meestal doe je dat niet in een header file sinds deze meestal door meerdere files worden gebruikt en je dus multiple definitions krijgt.
Dat maakt voor const definitions dus niet uit volgens Stroustrup. Gekker nog hij raadt et juist aan om het wel te doen:
The C++ Programmin Language Second Edition (Chapter 4, Section 4.3: Header Files):
A header file may contain:
code:
1
2
3
4
5
6
7
8
9
10
11
12
Type definitions            struct point { int x, y; };
Templates                   template<class T>
                                class V { /* ... */ }
Function declarations       extern int strlen(const char*);
Inline function definitions inline char get() { return *p++; }
Data declarations           extern int a;
Constant definitions        const float pi = 3.141593;
Enumerations                enum boo { false, true, };
Name declarations           class Matrix;
Include directives          #include <signal.h>
Macro definitions           #define Case break; case
Comments                    /* check for end of file */
Sorry for de layout van het lijstje ;)

[...]
The reason for recommending that the definition of simple constants, but not the definition of constant aggregates, can be placed in header files, is pragmatic. Most compilers are simply not smart enough to ensure that no redundant copies of constant aggregates are generated. Furthermore, the simple cases are far more common and therefore more important for generating good code.
Of dat met de huidige compilers nog geldt kan ik natuurlijk niet zeggen ;)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-05 23:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

Misschien een beetje mosterd na de maaltijd, maar:
BoAC schreef op 04 augustus 2004 @ 09:36:
[...]

Je declareert dus eigenlijk dubbel ;)
Extern gebruik je in een source-file om een variable te declareren en te gebruiken zoal curry684 zegt en dan later te gebruiken.
In een header-file staan alleen maar declaraties.
Nee, extern gebruik je in een header om aan te geven dat een bepaalde variabele bestaat, en niet per se in de huidige translation unit. Die header wordt geinclude door alle source files die die variabele willen gebruiken. In een van de source files wordt ie ook gedefinieerd, dit is over het algemeen de file die bij de header hoort

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.

Pagina: 1