"Byrial Jensen" <bjensen@nospam.dk> wrote in message
news:slrnae2b5j.113.bjensen@ask.ask...
> optimeres væk. Men når der er tale om globale data som deles mellem
> flere oversættelsesenheder, ser jeg ikke det helt store problem i at
> en defines virkefelt varer oversættelsesenheden ud (hvis den ikke
> undef'es). En global variabel eller enumeration varer lige så længe
> og kan ikke engang annulleres som en define kan.
Ja, en global variabel har lige så stort scope - nemlig oversættelsesenheden
ud.
Og dog!
const int foo = 42;
....
void f(int foo) // Kan du se visse problemer med at definere ovenstående med
en #define?
{
// ...
}
Men nånej, sådan noget kunne man aldrig komme til ved en fejltagelse, vel?
Jeg var engang ude for netop sådan et #define problem:
Det var et program skrevet i Borland Builder, og jeg fik en linkerfejl -
noget i stil med "Unresolved external void TServerSocket::SetPortA(int)"
Og jeg fattede ikke en brik - for TServerSocket (en Borland-klasse)
erklærede sgu ikke nogen SetPortA metode.
Jeg var RET længe om at opdage at problemet var windows.h. Den includede
indirekte en eller anden fil, som havde "#define SetPort SetPortA", og
vupti - så var metoden TServerSocket::SetPort omdøbt til SetPortA - både i
erklæringen og i brugen af den - kun linkeren kunne ikke lide det nye navn,
da man naturligvis linker med Borland's runtime-library, som kender
funktionen under navnet SetPort.
Formålet med "#define SetPort SetPortA" var naturligvis at "redirecte" alle
kald til SetPort til den nyere funktion (eller hvad ved jeg) SetPortA. Som
bivirkning havde den desværre at omdøbe ALT hvad der bar samme navn - uanset
scope! Selvfølgelig skulle den kun "omdøbe" den globale SetPort, men fordi
preprocessoren er totalt ligeglad med scopes (her specielt klassescopes), så
fik jeg den uheldige bivirkning.
Der var to mulige løsninger: (1) #include <windows.h>, #undef SetPort (hvor
fedt er det?), (2) vise mere omhu med rækkefølgen af includes (men så får
jeg compilefejl, hvis jeg kalder TServerSocket::SetPort, da compileren tror
jeg kalder TServerSocket::SetPortA - hvor fedt er det?)
Bjarke