2015-12-15 15 views
6

Im Lesung C++ Code, habe ich eine solche DefinitionHilfe in Bezug auf Makrodefinition benötigen

#define USE_VAL(X) if (&X-1) {} 

hat jemand Idee gefunden, was bedeutet es?

+1

Sie diese verwendet der nicht verwendeten Parameter Warnung loswerden? – LogicStuff

+0

Was den 'if' - Autor anbetrifft, versuchte vielleicht, dies zu tun: http://stackoverflow.com/questions/154136/do-while-and-if-else-statements-in-c-c-macroshttp://stackoverflow.com/questions/154136/do-while-und-wenn-sonst-statements-in-cc-macros – LogicStuff

+0

ich möchte wissen, wofür das verwendet wird, weil ich einen exist code habe, möchte mit diesem code –

Antwort

7

Basierend auf dem Namen, sieht es wie eine Möglichkeit aus, eine Warnung "unbenutzte Variable" loszuwerden. Die bestimmungsgemäße Verwendung ist wahrscheinlich so etwas wie folgt aus:

int function(int i) 
{ 
    USE_VAL(i) 
    return 42; 
} 

Ohne diese könnte man einen Compiler Warnung erhalten, dass der Parameter i innerhalb der Funktion nicht verwendet wird.

Es ist jedoch ein ziemlich gefährlicher Weg, dies zu tun, weil es Undefined Behavior in den Code einführt (Zeigerarithmetik jenseits der Grenzen eines tatsächlichen Arrays ist vom Standard nicht definiert). Es ist möglich, 1 an eine Adresse eines Objekts, aber nicht subtrahieren 1. Natürlich, mit + 1 anstelle von - 1, könnte der Compiler dann warnen "Bedingung immer wahr." Es ist möglich, dass der Optimierer die gesamte if entfernen wird und der Code bleibt gültig, aber Optimierer werden besser bei der Ausnutzung von "undefiniertem Verhalten kann nicht passieren", die tatsächlich den Code ziemlich vermasseln könnte.

Nicht zu erwähnen, dass für den betroffenen Typ überladen werden könnte, was möglicherweise zu unerwünschten Nebenwirkungen führt.

Es gibt bessere Möglichkeiten, eine solche Funktionalität Umsetzung wie Gießen void:

#define USE_VAL(X) static_cast<void>(X) 

jedoch meine persönliche Präferenz ist es, den Namen des Parameters in der Funktionsdefinition Kommentar aus, wie folgt aus:

int function(int /*i*/) 
{ 
    return 42; 
} 

Der Vorteil davon ist, dass es tatsächlich verhindert, dass Sie versehentlich den Parameter verwenden, nachdem Sie ihn an das Makro übergeben haben.

+0

Ja, für diesen letzten Ansatz. Es ist bei weitem das einfachste und beinhaltet nicht das Hinzufügen ** von Code, der absichtlich nichts tut, um eine Compiler-Warnung zu beruhigen. –

1

In der Regel wird eine Warnung "nicht verwendeter Rückgabewert" vermieden. Selbst wenn das übliche "cast to void" -Idiom normalerweise für nicht verwendete Funktionsparameter funktioniert, ist gcc mit -pedantic besonders streng, wenn die Rückgabewerte von Funktionen wie fread ignoriert werden (in der Regel Funktionen mit __attribute__((warn_unused_result)) markiert), also ein "fake if" wird häufig verwendet, um den Compiler zu überlisten, wenn er denkt, dass Sie etwas mit dem Rückgabewert machen.

+0

Sie können die Adresse eines R-Werts nicht verwenden, daher kann dies für die meisten Rückgabewerte nicht wirklich funktionieren. – Angew

0

Ein Makro ist eine Preprozessor-Direktive, das heißt, wo immer es verwendet wird, wird es durch den entsprechenden Code ersetzt.

und hier nach USE_VAL (X) den Raum erklären, was wird USE_VAL (X) tun.

Zuerst nehmen Sie die Adresse von x und dann 1 davon subtrahieren. Wenn es 0 ist, dann tu nichts.

wo USE_VAL (X) verwendet sie ersetzt wird durch die if (& X-1) {}

+0

Makros sind keine Funktionen. – LogicStuff

+0

Ja Makro ist nicht funktionsfähig. aber zum Verständnis kann man mit diesem Konzept denken. –

+0

@KashifArif Nein, NEIN, ** NEIN **. Denken Sie nicht an Makros als Funktionen. Sie sind * nicht einmal entfernt. * Ein Makro ist ein rein syntaktischer Ersatz. Das Nachdenken über Makros wie über Funktionen führt zu allen möglichen Fehlern und Missverständnissen. – Angew

Verwandte Themen