Makro wie komme ich zu diesen Wert?
-
Hallo!!
Ich habe folgendes Makro:
#define MIN(i,j) (i<j) ? i : j
Und rufe es mit folgende Werte auf:
int num = 2; int min = MIN(num + 5, num + 2)*3;
Wieso kommt hier der Wert 8 raus? Da ja j ausgewählt wird wäre das ja 4*3 und nicht 4 * 2 aber trotzdem kommt 8 raus! Kann mir jemand weiterhelfen stehe derzeit auf der Leitung!
mfg
-
num + 2 * 3 ist 8.
-
Ahhh verdammt punkt vor strich das hab ich übersehen
! Danke schön!!
mfg
-
Merke, dass Macros eine reine Textersetzung sind und man kann auch intressante Seiteneffekte haben, wie oben. Aus diesem Grund sieht man oft, dass man die Ausgabe extra mit Klammern versetzt:
#define MIN(i,j) (((i)<(j)) ? (i) : (j))
damit geht sowas wie
MIN(num + 5, num + 2)*3;
und bekommst 12 statt 8. Aber aufpassen, dass man trotzdem undefiniertes Verhalten haben kann:int val=8; val += MIN(9, ++val);
was denkst du, was da raus kommt? 17, 18, 19 oder was ganz anders? Das ist leider undefiniert. Also vorsicht mit solchen Makros, lieber eine (inline, sofern der Compiler das akzeptiert) Funktion verwenden, da ist man 100% auf der sichere Seite.
Ich mag Makros, denn man kann sich verdammt viel Tipparbeit sparen, aber ich verwende nie Makros wie min/max/usw wo Parameter mehrfach vorkommen, weil man damit sehr leicht undefiniertes Verhalten hervorrufen kann (wie oben gezeigt).
-
Ok!! Ich finde die Makros auch ziemlich klasse trotzdem blicke ich noch nicht ganz durch das Beispiel was ich gebracht hab war ein Teil eines Testbespiels!
Ich weiß auch was bei deinen Beispiel rauskommt nämlich 20 aber wie komme ich dazu?
Es wird mal ziemlich sicher 2 mal aufgerufen oder öfter?
mfg
-
hanni6al schrieb:
Ok!! Ich finde die Makros auch ziemlich klasse trotzdem blicke ich noch nicht ganz durch das Beispiel was ich gebracht hab war ein Teil eines Testbespiels!
was ist am "Makro sind reine Textersetzung" schwierig zu verstehen?
Wenn ich hab:
#define MIN(i,j) (i<j) ? i : j int min = MIN(num + 5, num + 2)*3;
dann wird, bevor kompiliert wird, den Code überführt in
$ gcc macro.c -E # 1 "macro.c" # 1 "<built-in>" # 1 "<command line>" # 1 "macro.c" int min = (num + 5<num + 2) ? num + 5 : num + 2*3;
die Zeilen, die mit # anfangen sind nur ein Hinweis für den Compiler, dass der C-Preprozessor am Werk war. Und
num + 2*3
ist nun Mal 8. Der C-Preprozessor ersetzt 1:1 das, das du im gibst. Dabei kann es passieren, dass man ungültigen Code erhält und sogar Syntaxfehler. Das ist der Nachteil an Makros, man muss stets wissen, was sie tun.hanni6al schrieb:
Ich weiß auch was bei deinen Beispiel rauskommt nämlich 20 aber wie komme ich dazu?
keine Ahnung, was raus kommt, es ist undefiniert, es könnte genausogut 100000000 rauskommen:
#define MIN(i,j) (i<j) ? i : j int val=8; val += MIN(9, ++val);
expadniert zu:
# 1 "macro.c" # 1 "<built-in>" # 1 "<command line>" # 1 "macro.c" int val=8; val += (9<++val) ? 9 : ++val;
und die letzte Zeile ist nun mal undefiniert.