Geben Sie einen Typ uintX_t ein, wobei X der Wert eines Makros ist

8

Ich habe ein Makro, WW , mit der Wortbreite in Bits, wie

%Vor%

Ich möchte einen neuen Typ, foo_t , als Alias ​​für eines der uintX_t in <stdint.h> deklarieren. Ich kann die Wortbreite hart codieren und

verwenden %Vor%

Allerdings ist uint(WW) offensichtlich ein Fehler. Ich habe eine Weile mit einem Makro wie #define expand(x) x herumgespielt und nutze es auf verschiedene Arten, ohne Erfolg. Mein letzter Ausweg ist eine #if -Kaskade wie

%Vor%

was ich lieber vermeiden würde. Gibt es eine Möglichkeit, einen Typ basierend auf meinem Makro WW zu schreiben, so dass uint(WW) schließlich auf uint64_t expandiert? Ich glaube, die Antwort ist "nein", aber einige Sprachanwälte beweisen mir bitte das Gegenteil.

    
Jens 06.09.2015, 12:04
quelle

2 Antworten

5

Aufgrund der Art und Weise, wie die Makroerweiterung funktioniert, benötigen Sie eine zusätzliche Indirektionsebene:

%Vor%

Live-Beispiel

    
Igor Tandetnik 06.09.2015, 13:10
quelle
2

Von C11dr n1570:

  

6.10.3.1 Argumentsubstitution

     

Nachdem die Argumente für den Aufruf eines funktionsähnlichen Makros identifiziert wurden,   Argumentsubstitution findet statt. Ein Parameter in der Ersetzungsliste, sofern nicht vorangestellt   durch ein # oder ## Vorverarbeitungstoken oder gefolgt von einem ## Vorverarbeitungstoken (siehe unten), ist   ersetzt durch das entsprechende Argument, nachdem alle darin enthaltenen Makros gefunden wurden   erweitert. Bevor sie ersetzt werden, sind die Vorverarbeitungstoken jedes Arguments   vollständig Makro ersetzt, als ob sie den Rest der Preprocessing-Datei gebildet hätten; kein anderer   Vorverarbeitungstoken sind verfügbar.

Grundsätzlich müssen Sie die Erweiterung über ein Aufrufmakro durchführen:

%Vor%

führt zu

%Vor%

Im Falle von expand(uint_(WW)) wird es auf sein einziges Argument erweitert, was bedeutet, dass expand(uint_(WW)) zu uint_(WW) wird. Da es Teil eines einzelnen Vorverarbeitungstokens ist, wird WW nicht erweitert. Aus diesem Grund könnten Sie expand(expand(expand(uint_(WW)))) haben, und es würde immer noch nicht funktionieren.

Bei uint(WW) wird es auf uint_(WW) erweitert. Der obige Absatz besagt jedoch, dass das Argument für uint einem Makroersatz unterliegt, also ist das Ergebnis tatsächlich uint_(<expansion of WW>) , weil das Argument WW Makro ersetzt wird. Das Makro uint_ wird dann mit dem ersetzten Wert von WW aufgerufen.

Der Grund dafür, dass WW direkt an das für typedef verantwortliche Makro übergeben wurde, ist nicht der Fall, weil WW Teil eines Ausdrucks ist, in den Token eingefügt werden ( ## ). "Ein Parameter in der Ersetzungsliste wird ersetzt, es sei denn, ihm wird ein # oder ## Vorverarbeitungstoken oder ein ## Vorverarbeitungstoken vorangestellt ..." ersetzt. "Dies bedeutet im Wesentlichen, dass ## die Expansion verhindert.

Sie können uint_(expand(WW)) nicht aus dem gleichen Grund verwenden: typedef uintexpand(WW)_t foo_t sieht nicht genau richtig aus, oder?

Sie können dies auch über ein allgemeineres PASTE3 -Makro erreichen:

%Vor%

Denken Sie auch daran, dass WW ein eigenständiger Ausdruck ist und vollständig durch Makros ersetzt wird. Dies bedeutet, dass unabhängig davon, wie viele Ebenen der Ersetzung vorhanden ist, diese erweitert wird, es sei denn, # oder ## stoppt die Erweiterung des Kurses:

%Vor%

ergibt:

%Vor%     
Chrono Kitsune 06.09.2015 13:16
quelle

Tags und Links