2017-02-04 5 views
-2

Ich habe diese Funktion und fügt eine Nummer hinzu.#define ADD (x) (x) + (x) gibt ein falsches Ergebnis zurück

#include <iostream> 
#include <string> 
#include <sstream> 

using namespace std; 

#define ADD(x) (x)+(x) 
int main() 
{ 
    int x = 2; 
    int y = ADD(++x); 

    cout << y << endl; 
} 

Wenn ich dieses Programm ausführen, gibt es 8 aber ich war 6.

erwarte ich dachte x = 3 und es wurde 3 an die ADD-Funktion zu senden, aber es scheint, wie es nicht der Fall ist. Kann mir das jemand erklären?

+0

Was gibt es zurück, wenn Sie nur ADD (2) aufrufen? –

+2

Es ist die alte Art, Inline-Funktion zu erstellen.Versuchen Sie das heute nicht mehr. –

+1

[Die Notwendigkeit für Klammern in Makros in C] (http://stackoverflow.com/q/10820340/995714) –

Antwort

9

Ihr Programm hat Verhalten nicht definiert, weil Sie die Prä-Betreiber fordern zweimal: int y = (++x)+(++x);. Hast du dafür keine Compiler-Warnung bekommen? Das Problem ist, dass ADDkeine Funktion ist. Es ist ein Makro; es führt Textersatz durch. Verwenden Sie keine Makros für solche Dinge in C++.

Wenn Sie das Makro in eine Funktion einschalten, wird alles gut funktionieren, weil dann ++x nur einmal erscheint:

#include <iostream> 

template <class T> 
T add(T x) 
{ 
    return x + x; 
} 

int main() 
{ 
    int x = 2; 
    int y = add(++x); 

    std::cout << y << '\n'; 
} 
+1

Was 'cout << hinzufügen (++ x) << endl;' wird sich ergeben? Anstatt die Rückgabe in 'y' zu speichern. – Raindrop7

+0

@ Raindrop7: Warum fragst du? Wurde das Ergebnis von 'add' nicht gedruckt, als Sie es versuchten? –

+0

Danke, ich verstehe es jetzt :) – Berkin

1

Es ist undefined Verhalten.

Wenn Ihr Compiler vorverarbeitet das Makro hier:

int y = ADD(++x); 

wird es

int y = (++x)+(++x); 

Es gibt keine festgelegte Reihenfolge, in der Argumente ausgewertet werden.

Weitere Informationen finden Sie Why are these constructs (using ++) undefined behavior?

+0

Coprozessor-Stufe? – Peter

+0

@Peter Danke für den Vorschlag. Ich habe Korrektur gemacht. – rsp

1

Makros sind nicht real C++ Funktionen. Es ersetzt nur Text.

Ihr Code:

int y = ADD(++x); 

wird ersetzt durch:

int y = (++x)+(++x); 

Sie können anstelle der Makro eine Template-Funktion verwenden.

template<typename T1, typename T2> 
inline auto add(T1 x, T2 y) 
{ 
    return x + y; 
} 
+1

Erwähnenswert, dass 'auto' Rückgabetypen in C++ 14 eingeführt wurden und nicht im C++ 11-Modus funktionieren. –

0

Da ADD(x) ist eigentlich ein Makro (im Gegensatz zu einer realen Funktion gegen), ADD(++x) ausgewertet (++x) + (++x), die überhaupt nicht schön ist, weil diese die gleiche Variable ändert, x, zweimal in einer Erklärung. Das Ergebnis solcher Modifikationen ist nicht definiert.

In Ihrem speziellen Fall des Compilers, den Wert von x 2 bis 3 erhöht, und es dann von 3 bis 4 erhöht, während der Wert von x, um das Lesen (x+x) auszuführen, sie entschied sich für die neueste Wert zu lesen, die ist 4.

Ich würde vorschlagen, dass Sie über die Unterschiede zwischen Makros und Funktionen nachlesen.