Font
[thread]1091[/thread]

Stringification: im Gnu C Präprozessor



<< |< 1 2 >| >> 13 entries, 2 pages
betterworld
 2003-11-15 22:32
#11561 #11561
User since
2003-08-21
2613 articles
ModeratorIn

user image
Kann man Makros, die z. B. Zahlen darstellen, zu Strings machen? Die Dokumentation beschreibt eine Methode fur Makroargumente. Die funktioniert aber auch wirklich nur fuer Makroargumente, nicht fuer Makros. Beispiel aus der Dokumenation:
Code: (dl )
1
2
3
4
     #define WARN_IF(EXP) \
    do { if (EXP) \
            fprintf (stderr, "Warning: " #EXP "\n"); } \
    while (0)


Was ich aber gerne haette, ist folgendes:
Code: (dl )
1
2
3
4
5
6
7
8
#define MAX_RECURSIONS 40

...

if(rec > MAX_RECURSIONS){
 fprintf(stderr, "Too many recursions (" #MAX_RECURSIONS ")\n");
 exit(1);
}


Das funktioniert aber nicht. Okay, ich koennte natuerlich ein %d einfuegen und fprintf die Zahl in einen String wandeln lassen. Das passiert aber dann zur Laufzeit und ist so furchtbar langsam ;) ;) Es kommt mir halt darauf an, dass es doch theoretisch eine "schoene" Loesung geben muesste.

Danke fuer Antwort
esskar
 2003-11-15 22:49
#11562 #11562
User since
2003-08-04
7321 articles
ModeratorIn

user image
du wirst es aber nicht schon bei der compilezeit merken können, da der compiler ja noch nicht weiß, ob rec jemals > MAX_RECURSIONS ist...

das passt direkt zum Thread: Dave Hobbits Hotel ...
das ist nämlich ein Element der Menge von Problemen, die nicht gelöst werden können - zumindest nicht mit einer programmiersprache... (Stichwort: Halteproblem)
esskar
 2003-11-15 22:54
#11563 #11563
User since
2003-08-04
7321 articles
ModeratorIn

user image
oder willst du einfach nur den string in der compilezeit berechnen?

Code: (dl )
1
2
3
4
5
6
7
#define ERROR_RECURSION(n) \
do { if (n) \
fprintf (stderr, "Too many recursions (" #n ")\n"); \
exit(0); \
while (0)

if(rec > MAX_RECURSIONS) ERROR_RECURSION(MAX_RECURSIONS);
betterworld
 2003-11-15 22:58
#11564 #11564
User since
2003-08-21
2613 articles
ModeratorIn

user image
[quote=esskar,15.11.2003, 21:49]du wirst es aber nicht schon bei der compilezeit merken können, da der compiler ja noch nicht weiß, ob rec jemals > MAX_RECURSIONS ist...[/quote]
Doch. Ich habe es wohl nicht ganz deutlich gesagt: Die if-Anweisung muss natuerlich zur Laufzeit ausgewertet werden. Was ich aber nicht zur Laufzeit haben moechte, ist die Konvertierung vom int zum String.
Ich moechte also praktisch zwei Makros haben, mit den Werten 40 und "40". Nur waere es ja dumm, die beide selbst zu schreiben. Ich habe es noch so versucht:
Code: (dl )
#define TOSTRING(x) #x

Aber dann wird TOSTRING(MAX_RECURSIONS) nicht etwa zu "40", sondern zu "MAX_RECURSIONS" :(
betterworld
 2003-11-15 23:01
#11565 #11565
User since
2003-08-21
2613 articles
ModeratorIn

user image
[quote=esskar,15.11.2003, 21:54]oder willst du einfach nur den string in der compilezeit berechnen?

Code: (dl )
1
2
3
4
5
6
7
#define ERROR_RECURSION(n) \
do { if (n) \
   fprintf (stderr, "Too many recursions (" #n ")\n"); \
   exit(0); \
while (0)

if(rec > MAX_RECURSIONS) ERROR_RECURSION(MAX_RECURSIONS);
[/quote]
OK, das ist ein anderer Ansatz, aber sieht nicht schlecht aus. Den koennte ich vielleicht nehmen. Danke
esskar
 2003-11-15 23:08
#11566 #11566
User since
2003-08-04
7321 articles
ModeratorIn

user image
finde denn aufwand für ein abbruch makro aber übertrieben...
vorallem wenn du mit Laufzeit argumentierst...
ich mein, danach ist das Programm eh rum!
betterworld
 2003-11-15 23:09
#11567 #11567
User since
2003-08-21
2613 articles
ModeratorIn

user image
[quote=esskar,15.11.2003, 21:54]
Code: (dl )
1
2
3
4
5
6
7
#define ERROR_RECURSION(n) \
do { if (n) \
   fprintf (stderr, "Too many recursions (" #n ")\n"); \
   exit(0);} \
while (0)

if(rec > MAX_RECURSIONS) ERROR_RECURSION(MAX_RECURSIONS);
[/quote]
Sorry, funktioniert doch nicht. Das ist genau dasselbe Problem:
Ausgabe ist: Too many recursions (MAX_RECURSIONS)
betterworld
 2003-11-15 23:13
#11568 #11568
User since
2003-08-21
2613 articles
ModeratorIn

user image
Jetzt habe ich die Loesung. Weiter unten in der Dokumentation stand:
Quote
If you want to stringify the result of expansion of a macro argument,
you have to use two levels of macros.

#define xstr(s) str(s)
#define str(s) #s
#define foo 4
str (foo)
==> "foo"
xstr (foo)
==> xstr (4)
==> str (4)
==> "4"


Wenn ich nun also Deine Idee damit kopple, komme ich zu
Code: (dl )
1
2
3
4
5
#define ERROR_RECURSION(n) \
do { if (n) \
fprintf (stderr, "Too many recursions (" str(n) ")\n"); \
exit(0);} \
while (0)


Ist ja pervers
esskar
 2003-11-15 23:38
#11569 #11569
User since
2003-08-04
7321 articles
ModeratorIn

user image
jep...
kennst du schon META_IF's ?

mehr dazu in ner Vorlesung, die ich letztes Jahr gehört hatte:
Algorithm Library Design .. Scripte dazu findest du unter Algorithm Library Design: Lecture Notes ...
Viel Spaß!
betterworld
 2003-11-16 03:45
#11570 #11570
User since
2003-08-21
2613 articles
ModeratorIn

user image
Ich habe mir das gerade mal angeschaut. Das kann wohl manchmal ganz hilfreich sein. Aber wenn man mit so etwas anfaengt, besteht irgendwann der ganze Code nur noch aus Templates, was dann auch ziemlich unuebersichtlich ist. Ich denke da mit Grauen an Situationen, wo ich irgendwelche Informationen in den STL-Headern gesucht habe. Ich komme mit Templates auch nicht so gut klar. Wenn ich mal sie mal etwas staerker benutzen will, wollen sie irgendwann nicht mehr so, wie ich will.
Ausserdem dauert das immer Ewigkeiten zum Kompilieren.
<< |< 1 2 >| >> 13 entries, 2 pages



View all threads created 2003-11-15 22:32.