2017-02-07 4 views
5

Imagine Ich möchte #define ein Makro, so dass es gleich aktuellen Wert eines anderen Makros ist (wenn ein solches Konzept existiert).Kann ich den zugrunde liegenden Wert eines Makros beim Definieren eines anderen Makros erfassen?

Zum Beispiel:

#include "def_a.h" // defines macro A 
#define B A 

Dies definiert BA zu sein. Wenn A später die Definition ändert (d. H. Durch eine Neudefinition), ändert sich auch der Wert von B (weil B am Anwendungsort auf A expandiert, was sich weiter auf den neuen Wert A ausdehnt).

Was ich möchte, ist eine Möglichkeit, zu „backen in“ den Wert von A in B so dass B erweitert nur auf den Wert von A, nicht A selbst.

Zum Beispiel:

#define A first 
#define B BAKE_IN(A) 
#undef A 
#define A second 
#define C BAKE_IN(A) 
#undef A 
#define A third 

// here I want B to expand to first, and C to expand to second 

Natürlich BAKE_IN ist nicht eine reale Sache, aber ich frage mich, ob es irgendeine Art und Weise ist diese Wirkung zu erzielen.

Jetzt habe ich nicht wirklich gesagt, was passieren soll, wenn A selbst in Bezug auf andere Makros definiert ist, aber ich bin OK sowohl mit "einer Ebene der Erweiterung" (dh B bekommt den Wert von A erweitert wird , also bleiben weitere Makros übrig) und auch "volle Expansion" (dh A ist vollständig rekursiv expandiert, so wie es an einem Verwendungsort wäre).

+0

Warum Sie die zu viel Pflege Schritte der Substitution und nicht über das Endergebnis. '#define B A' ist ausreichend, um den Wert von A zu erhalten, aber mit zwei Schritten. Die Anzahl der Upvote zu sehen, bekam nicht, was ich hier vermisse. Ich habe das Gefühl, dass Sie den langen Weg nach Rom nehmen wollen. – Sabrina

+1

Ok, ich war mir nicht sicher ... weiß jemand, wie man eine Frage als Duplikat kennzeichnet, ohne sie zu schließen? –

+1

Soweit ich weiß, schließen sich diese gegenseitig aus.Wenn eine Frage als Duplikat gekennzeichnet ist, wird sie mit dem kleinen Banner oben geschlossen, das Sie zu der alten Frage führt. – BeeOnRope

Antwort

1

Makros werden nie im Rumpf einer #define Direktive ersetzt, daher gibt es keine Möglichkeit, ein Makro als aktuellen Wert eines anderen Makros zu definieren, außer für den begrenzten Fall von Makros, deren Wert ein konstanter arithmetischer Ausdruck ist.

Im letzteren Fall, Sie BOOST_PP_ASSIGN_SLOT vom Boost preprocessor library. verwenden können (die meisten der Boost-Bibliotheken sind Obwohl C++ -. Spezifisch, die Boost-Präprozessor Bibliothek funktioniert sowohl für C und C++, und hat auf jeder anderen Boost-Komponente keine Abhängigkeit)

+0

Ihre "Ausnahme" ist eigentlich keine. Und das ist C, nicht C++. – Olaf

+1

@olaf: Die Boost-Präprozessorbibliothek funktioniert sowohl in C als auch in C++. – rici

+0

@Olaf - Arbeitet die zugrundeliegende Technik 'BOOST_PP_ASSIGN_SLOT' dann in C, oder sind die Präprozessorregeln anders? – BeeOnRope

1

Ich glaube nicht, dass es eine saubere Lösung gibt. Die nächste Sache, die ich gefunden ist „Zeichenfolge“ Werte innerhalb char Arrays zu erhalten:

#include <stdio.h> 

#define BAKE_IN(X, id) BAKE_IN_REAL(X ## _, X, id) 
#define BAKE_IN_REAL(X, Y, id) static const char X ## id[] = #Y; 
#define BAKE_OUT(X, id) X ## _ ## id 

#define A first 
BAKE_IN(A, 1) 
#define B BAKE_OUT(A, 1) 
#undef A 

#define A second 
BAKE_IN(A, 2) 
#define C BAKE_OUT(A, 2) 
#undef A 

int main(void) 
{ 
    printf("%s\n", B); // prints "first" 
    printf("%s\n", C); // prints "second" 
    return 0; 
} 

Die Idee ist, dass BAKE_IN Makro Objekt wie zum Beispiel dem Namen deklariert A_1, die die aktuelle Erweiterung von A enthält.

Es gibt zwei wichtige Einschränkungen:

  • Jedes Paar BAKE_IN und BAKE_OUT eindeutige ID
  • Die Erweiterung muss, ist nur in „Zeichenfolge“ Form
+0

Danke! Dies ist sehr nützlich, wenn Sie eine String-Version des Makros benötigen, was bei einigen Diagnosetypen der Fall ist. Daher werde ich das wahrscheinlich in Zukunft verwenden. Ich habe die andere Antwort in diesem Fall akzeptiert, weil sie direkter anwendbar war (da ich für meinen Anwendungsfall definitiv kein Textformular benötige), aber das ist ein guter Beitrag. – BeeOnRope

Verwandte Themen