/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
Preprocessor udfordring
Fra : Jesper Wolf Jesperse~


Dato : 17-01-02 10:39

Jeg vil gerne kunne identificere hvilken del af mit program der laver
fejludskrifter og har til dette formål opfundet en makro som skal bruges i
fejludskrifterne.
Under Borland C har man en predefineret macro __FUNC__ som fint dækker
formålet, men under andre compilere må man nøjes med de standardiserede
__FÌLE__ og __LINE__.
Mit problem er så at opnå en streng concatenering af disse to således at det
kan bruges i fejludskriften.

Foreløbigt har jeg en header fil der indeholder følgende macro:
---- cut
#ifdef __BORLANDC__
#define WHERE "(" __FUNC__ ")"
#else // this does not
work right
#define WHERE "(" __FILE__ ": __LINE__ " ")"
#endif
--- cut ---

Den bruges i en sammenhæng som denne her:

--- cut ---
throw eComException(WHERE, "ved logoff");
--- cut ---

Men her bliver __LINE__ makroen ikke substitueret da den står i en streng.

Men hvordan får jeg skidtet til at virke uden at skulle lave noget ala
sprintf (buffer, "%s:%d, __FILE__, __LINE__) ?

Det skal kunne håndteres af preprosessoren alene.

Jeg har forsøgt med en makro der tager argumenter og konvertere andet
argument til en streng med # operatoren, det har samme resultat som
ovenstående.
Jeg har også prøvet concatenerings operatoren ## men det får jeg heller ikke
noget godt ud af.

Har i gode forslag ?

PS. Det drejer sig om C++, men der er ikke megen forskel på preprocessoren i
C++ og ansi C.


Med venlig hilsen
Jesper Wolf Jespersen



 
 
Byrial Jensen (17-01-2002)
Kommentar
Fra : Byrial Jensen


Dato : 17-01-02 20:01

Jesper Wolf Jespersen <spam.jwj@ehuset.com.spam> skrev:
> #define WHERE "(" __FILE__ ": __LINE__ " ")"

> Men her bliver __LINE__ makroen ikke substitueret da den står i en streng.

Korrekt.

> Men hvordan får jeg skidtet til at virke uden at skulle lave noget ala
> sprintf (buffer, "%s:%d, __FILE__, __LINE__) ?
>
> Det skal kunne håndteres af preprosessoren alene.

Jeg tror ikke at det kan lade sig på standardiseret vis.

> Jeg har forsøgt med en makro der tager argumenter og konvertere andet
> argument til en streng med # operatoren, det har samme resultat som
> ovenstående.

Korrekt, #-operatoren i en makrodefinition forhindrer ekspansion af
makroer i kaldet af makroen.

> Jeg har også prøvet concatenerings operatoren ## men det får jeg heller ikke
> noget godt ud af.

Nej.

> Har i gode forslag ?

Desværre.

> PS. Det drejer sig om C++, men der er ikke megen forskel på preprocessoren i
> C++ og ansi C.

Mine bemærkninger gælder ANSI C.

Anders Borum (17-01-2002)
Kommentar
Fra : Anders Borum


Dato : 17-01-02 22:09

"Jesper Wolf Jespersen" <spam.jwj@ehuset.com.spam> skrev i en meddelelse
news:RYw18.50$lw2.2007@news.get2net.dk...
[klip]
'> Det skal kunne håndteres af preprosessoren alene.
>
> Jeg har forsøgt med en makro der tager argumenter og konvertere andet
> argument til en streng med # operatoren, det har samme resultat som
> ovenstående.
> Jeg har også prøvet concatenerings operatoren ## men det får jeg heller
ikke
> noget godt ud af.
>
> Har i gode forslag ?

Her er mit forslag. Det virker med gcc 2.95.3-5 men _ikke_ med Visual C++
6.0.
Inspirationskilden er Boost-bibliotekerne som har været oppe og vende
tidligere her i gruppen.

///////////////////
#include <stdio.h>

#define STR(E) DELAY(E)
#define DELAY(E) #E

#define WHERE "(" __FILE__ ": " STR (__LINE__) ")"

void main() {
puts(WHERE);
puts(WHERE);
}

///////////////////

Hilsen Anders




Martin M. Pedersen (21-01-2002)
Kommentar
Fra : Martin M. Pedersen


Dato : 21-01-02 20:50

Hej,

"Anders Borum" <overflade@fedt.dk> wrote in message
news:V5H18.1151$Eu2.118488@news010.worldonline.dk...

> Her er mit forslag. Det virker med gcc 2.95.3-5 men _ikke_ med Visual C++
> 6.0.

Det bør altid virke, og det gør det da også her hos mig med Visual C++ 6.0
(version 12.00.8168). Er der mon forskel på service packs her?

mvh.
Martin





Jonas Meyer Rasmusse~ (21-01-2002)
Kommentar
Fra : Jonas Meyer Rasmusse~


Dato : 21-01-02 21:20

Hejsa.
"Martin M. Pedersen" <mmp@www.moeller-pedersen.dk> wrote in message
news:3c4c70f6$0$89091$edfadb0f@dspool01.news.tele.dk...
> Det bør altid virke, og det gør det da også her hos mig med Visual C++ 6.0
> (version 12.00.8168). Er der mon forskel på service packs her?

Min oversætter VC7, beta2,
duer det ikke
det oversætter fint, men istedet for at sætte linie nummeret ind, så sætter
det "__LINE__" ind i strengen.
måske det er det som du har overset, og det som Anders oprindeligt mente?

mvh Jonas



Anders Borum (22-01-2002)
Kommentar
Fra : Anders Borum


Dato : 22-01-02 10:55

"Jonas Meyer Rasmussen" <meyer_remove_@diku.dk> skrev i en meddelelse
news:a2ht52$qe2$1@eising.k-net.dk...
> Hejsa.
> "Martin M. Pedersen" <mmp@www.moeller-pedersen.dk> wrote in message
> news:3c4c70f6$0$89091$edfadb0f@dspool01.news.tele.dk...
> > Det bør altid virke, og det gør det da også her hos mig med Visual C++
6.0
> > (version 12.00.8168). Er der mon forskel på service packs her?

Jeg bruger også 12.00.8168

> Min oversætter VC7, beta2,
> duer det ikke
> det oversætter fint, men istedet for at sætte linie nummeret ind, så
sætter
> det "__LINE__" ind i strengen.
> måske det er det som du har overset, og det som Anders oprindeligt mente?

Ja - den udskriver følgende:
(e:\documents and settings\ander\skrivebord\cpp1.cpp: (__LINE__Var+1))
(e:\documents and settings\ander\skrivebord\cpp1.cpp: (__LINE__Var+2))




Richard Flamsholt (17-01-2002)
Kommentar
Fra : Richard Flamsholt


Dato : 17-01-02 23:35

"Jesper Wolf Jespersen" <spam.jwj@ehuset.com.spam> skrev:
>Mit problem er så at opnå en streng concatenering af disse to

At lave værdien af et preprocessorsymbol om til at streng er svjv ikke
muligt. Desværre.

> throw eComException(WHERE, "ved logoff");

Et alternativ var at ændre eComException() til at tage en eksplicit
streng og linienummer og lade den om at sprintf'e. Derved isoleres al
den trælse sprintf-kode (med at sikre en stor nok buffer osv osv) ét
sted og udføres kun når der faktisk kastes en exception.

Streng+linienummer skulle naturligvis stadig overføres "automatisk" vha
__FILE__,__LINE__ på en eller anden måde. En simpel implementation kunne
være blot at #define WHERE __FILE__,__LINE__ .

--
Richard Flamsholt
richard@flamsholt.dk - www.richard.flamsholt.dk

Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408925
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste