Hallo zusammen, ich verzweifele an folgendem Problem, brauche Hilfe: ----------------- int16_t adcval #define adcvalMaxY 230 #define adcvalMinY 30 #define MiddleY ((adcvalMaxY - adcvalMinY)/2) + adcvalMinY //#define MiddleY 130 Wenn ich nun die folgenden Audrücke berechne (mit adcval = 155) dann ergibt (adcval - MiddleY) den Wert 85 (MiddleY - adcval) den Wert -25 Wenn ich nun umkommentiere //#define MiddleY ((adcvalMaxY - adcvalMinY)/2) + adcvalMinY #define MiddleY 130 dann ergibt (adcval - MiddleY) den Wert 25 (MiddleY - adcval) den Wert -25 Was ist denn hier los ?? Ich bin total ratlos! Grüsse
Autsch - jetzt habe ich es kapiert ...! Der Pre-Processor ersetzt den Ausdruck (adcval - MiddleY) zu ( adcval - ((230 - 30)/2) + 30 ) ... und nicht zu zu ( adcval - ( ((230 - 30)/2) + 30) ) Gefährliche Falle ...! Danke
Yep. Wie du schon bemerkt hast, ist es immer eine gute Idee ein Makro zu Klammern wenn es eine Formel darstellen soll. Aber es gibt noch mehr Fallen mit Makros. #define DOUBLE(x) (2 * x) und jetzt lass mal berechnen i = 5; j = DOUBLE(i+1) Das Ergebnis ist nicht 12, sondern 11. Die Makroexpansion zeigt auch warum. Aus DOUBLE(i+1) wird j = ( 2 * i+1 ); und Aufgrund der Matheregeln wird das als (2*i)+1 gerechnet. Lösung: #define DOUBLE(x) ( 2 * (x) ) Das ist aber nicht alles. Es gibt noch mehr. Gefährlich wird es auch immer dann, wenn ein Makroargument in der Expansion 2 mal vorkommt #define MAX(x,y) ( (x) < (y) ? (y) : (x) ) und das wendest du mal auf i = 5; j = 6; k = MAX(i++,j++) an. Welches sind die Werte von i und j nach der Maximumbestimmung? i hat dann den Wert 6, aber j hat den Wert 8! Aus diesen Gründen ist man bei Formeln meist mit einer Funktion auf der besseren Seite int max( int x, int y ) { return x < y ? y : x; } Da gibt es keine derartigen überraschenden Effekte. Und da der Compiler solche Funktionen in den meisten Fällen inlinen wird, hat man auch keinen Laufzeit-Penalty.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.