2016-07-23 33 views
4

In den Makrodefinitionen unten, ist es 2 Dereferenzierungsebenen vor dem eigentlichen Einfügen Betrieb:Warum 2 Dereferenzierungsebenen in Definition von Makro-## Operation

#define MACRO_JOIN(a, b) MACRO_JOIN1(a, b) 
#define MACRO_JOIN1(a, b) MACRO_JOIN2(a, b) 
#define MACRO_JOIN2(a, b) a##b 

Ich weiß, dass wir MACRO_JOIN1 brauchen, weil es kein Einfügen oder Stringing, damit seine Argumente zuerst erweitert werden können.

Aber was genau ist der Zweck der zweiten Indirektion MACRO_JOIN? In welchen Situationen wird MACRO_JOIN funktionieren, aber MACRO_JOIN1 wird fehlschlagen?

Antwort

6

Das Erzwingen einer zusätzlichen Erweiterung kann einen Unterschied machen, wenn die ursprüngliche Erweiterung zu etwas führt, das weiter erweitert werden kann. Ein triviales Beispiel gegeben:

#define MACRO(x) x 
#define EXPAND(x) x 
#define NOEXPAND() 

ist:

MACRO NOEXPAND() (123) 

Dies erweitert zu MACRO (123). Auf der anderen Seite, wenn Sie eine zusätzliche Erweiterung erzwingen, etwa so:

EXPAND(MACRO NOEXPAND() (123)) 

Ergebnisse in:

123 

Normalerweise zwingt zusätzliche Erweiterungen wie diese ist nicht notwendig: alle Makrodefinitionen, die dazu führen, würde dies zu Irgendwelche Unterschiede sind sowieso generell als armer Stil anzusehen. Aber mit bestimmten spezifischen Eingaben kann es nützlich sein.

Also für ein konkretes Beispiel mit Ihrem MACRO_JOIN:

MACRO_JOIN(123, MACRO NOEXPAND() (456)) // expands to 123456 
MACRO_JOIN1(123, MACRO NOEXPAND() (456)) // expands to 123MACRO (456) 
+0

erstaunliche Erklärung! Ich muss diese speziellen Testfälle auf meinen cpp Implementierungen versuchen ... – chqrlie

+0

Ich sehe. Ich dachte, dass sein Zweck es wäre, etwas zu "zwingen", aber ich habe nie über diese Art von Anwendungen nachgedacht. Noch eine Frage: In deinem Beispiel ist das Makro 'NOEXPAND()' fast nutzlos. Gibt es einen Fall, in dem wir davon Gebrauch machen können? –

+0

@ PJ.Hades Wie ich schon sagte, werden Makrodefinitionen, bei denen es einen Unterschied macht, generell als schlechter Stil betrachtet. Jedes Beispiel, das ich mir vorstellen könnte, wäre genauso nutzlos wie 'NOEXPAND()'. Ich würde also sagen, mach dir keine Sorgen darüber, es sei denn, du findest tatsächlich einen Anwendungsfall mit Makrodefinitionen, die du verwendest. – hvd