Wie implementiere ich ein generisches Makro in C?

8
%Vor%

Wenn param char * ist, senden Sie sie an func_string .

Wenn es int ist, senden Sie es an func_int

Ich denke, dass es eine Lösung dafür geben kann, da Variable Typen zur Kompilierzeit bekannt sind.

    
lexer 31.08.2011, 11:21
quelle

6 Antworten

11

Dies wird mit C1X möglich sein, aber nicht im aktuellen Standard.

Es wird so aussehen:

%Vor%     
Constantinius 31.08.2011 11:24
quelle
10

Variablentypen sind dem Compiler bekannt, nicht jedoch dem Präprozessor (der den Code einfach als unstrukturierten Text bezeichnet) und nur einfache Ersetzungsoperationen ausführt. Ich fürchte, Sie können das nicht mit C-Makros erreichen.

In C ++ haben sie Vorlagen erfunden, um solche Probleme zu lösen (und mehr).

    
Péter Török 31.08.2011 11:23
quelle
5

Sie können die Eigenschaften der Typen testen.

Beispielsweise kann int einen negativen Wert enthalten, während char* dies nicht kann. Also, wenn ((typeof(param))-1) < 0 , param unsigniert ist:

%Vor%

Der Compiler optimiert dies offensichtlich.

Versuchen Sie es hier: Ссылка

Dies wäre noch einfacher, wenn die Typen unterschiedliche Größen hätten. Wenn Sie beispielsweise ein generisches Makro schreiben möchten, das verschiedene Zeichengrößen verarbeiten kann:

%Vor%

GCC hat eine __builtin_types_compatible_p() eingebaute Funktion, die überprüft werden kann für die Kompatibilität der Typen:

%Vor%

Versuchen Sie es hier: Ссылка

Sie können dies in ein Makro einfügen, um das zu erreichen, was Sie tun möchten:

%Vor%

(Das ({...}) ist ein GCC-Statement-Ausdruck , erlaubt es einer Gruppe von Aussagen, ein rvalue zu sein.

Der __builtin_choose_expr() Built-in kann den zu kompilierenden Ausdruck auswählen . Mit __builtin_types_compatible_p kann ein Fehler zur Kompilierzeit ausgelöst werden, wenn der Param-Typ nicht sowohl mit int als auch mit char* kompatibel ist: (durch Kompilieren von sashting in diesem Fall ungültig)

%Vor%

Dies ist ein leicht abgewandeltes Beispiel aus __builtin_choose_expr docs .

    
arnaud576875 31.08.2011 11:48
quelle
4

Es gibt keine Möglichkeit, in C89 / ANSI C Zeitprüfungsarten auszuführen, aber es gibt eine Erweiterung für gcc, die dies zulässt. typeof oder etwas in diesen Zeilen, wenn ich mich erinnere. Ich habe es einmal im Linux Kernel gesehen.

In kernel.h :

%Vor%

Sehen Sie sich diesen Artikel an: GCC-Hacks im Linux-Kernel

Als ich das zum ersten Mal gesehen habe, habe ich hier eine Frage zu SO gestellt:

min Makro in kernel.h

Ich bin mir nicht ganz sicher, wie genau du es benutzen würdest, um dein Problem zu lösen, aber es ist etwas, das einen Blick wert ist.

    
Robert S. Barnes 31.08.2011 11:25
quelle
1

Sie können dies nicht mit einem Makro tun. Macros Wert wird zur Kompilierzeit ersetzt und nicht interpretiert. Sie sind nur Substitutionen.

    
Heisenbug 31.08.2011 11:24
quelle
1

Variablentypen sind tatsächlich zur Kompilierzeit bekannt, jedoch findet vor der Kompilierung eine Makroexpansion statt. Ich schlage vor, dass Sie 2 überladene Funktionen anstelle eines Makros implementieren.

    
Luchian Grigore 31.08.2011 11:25
quelle