2009-10-13 7 views
18

Wie die Fragen sagt, ist der C Preprozessor in der Lage, es zu tun?Kann der C-Präprozessor Integer-Arithmetik ausführen?

Z. B .:

#define PI 3.1416 
#define OP PI/100 
#define OP2 PI%100 

Gibt es eine Möglichkeit OP und/oder OP2 in der Vorlaufphase berechnet werden?

+4

PI keine ganze Zahl in dem Beispiel; Daher wären weder OP noch OP2 Ganzzahlen, wenn der Präprozessor gezwungen wäre, sie zu bewerten. Und die Operanden von '%' können keine Fließkommazahlen sein. –

Antwort

25

Ganzzahlarithmetik? Führen Sie das folgende Programm, um herauszufinden:

#include "stdio.h" 
int main() { 
    #if 1 + 1 == 2 
     printf("1+1==2\n"); 
    #endif 
    #if 1 + 1 == 3 
     printf("1+1==3\n"); 
    #endif 
} 

Antwort „ja“ lautet, gibt es eine Möglichkeit der Präprozessor ausführen Integer-Arithmetik zu machen, die es in einem Prä-Prozessor Zustand zu verwenden ist.

Beachten Sie jedoch, dass Ihre Beispiele keine Integer-Arithmetik sind. Ich habe gerade überprüft, und GCCs Präprozessor schlägt fehl, wenn Sie versuchen, Float-Vergleiche durchzuführen. Ich habe nicht überprüft, ob der Standard jemals Gleitkommaarithmetik im Präprozessor erlaubt.

Regular Makroerweiterung nicht ausgewertet integer Ausdrücke, es es an den Compiler verlässt, kann als durch eine Vorverarbeitung (-E in gcc) folgendes zu sehen:

#define ONEPLUSONE (1 + 1) 
#if ONEPLUSONE == 2 
    int i = ONEPLUSONE; 
#endif 

Ergebnis ist int i = (1 + 1); (plus wahrscheinlich ein paar Sachen um Quelldateinamen und Zeilennummern anzugeben und so).

+6

Chris: Wir leben jetzt in der Zukunft, und während die fliegenden Autos noch fehlen, sind Standard-Rückgabewerte von der Hauptfunktion angekommen! –

+11

@Chris: Eine geschweifte Klammer, die den Wert "0" zurückgibt (5.1.2.2.3, Programmbeendigung). Wenn ich in einer mit "C" gekennzeichneten Frage nicht den Standard C annehmen darf, worauf kommt dann die Welt? Kannst du nicht jemanden finden, der // - Kommentare im Code verwendet, die von einem C89 - Compiler gesehen werden könnten, und sich stattdessen über sie beschweren? ;-) –

+0

@Chris - Die schließende Klammer? :-) –

13

Der Code, den Sie geschrieben haben, bewirkt nicht, dass der Präprozessor irgendeine Berechnung ausführt. Ein #define tut einfach das Ersetzen von Text, so mit diesem definiert:

#define PI 3.1416 
#define OP PI/100 

Dieser Code:

if (OP == x) { ... } 

wird

if (3.1416/100 == x) { ... } 

und dann wird es kompiliert. Der Compiler wiederum können einen solchen Ausdruck nehmen und es bei der Kompilierung berechnen und einen Code entspricht dies produzieren:

if (0.031416 == x) { ... } 

Aber das ist der Compiler, nicht der Präprozessor.

Um Ihre Frage zu beantworten, ja, kann der Präprozessor einige Arithmetik durchführen. Das kann man sehen, wenn man so etwas schreiben:

#if (3.141/100 == 20) 
    printf("yo"); 
#elif (3+3 == 6) 
    printf("hey"); 
#endif 
+3

Leider, wenn Sie versuchen, Ihre bedingte Compilation-Snippet, erhalten Sie die Nachricht von GCC:' x.c: 5: 6: Fehler: Gleitkommazahl im Präprozessor Ausdruck '. Sie können Integer-Arithmetik mit dem C-Preprozessor ausführen; Sie können keine Fließkomma-Arithmetik mit ihm ausführen. –

+0

sieht aus wie gcc hier abgeschnittene Ecken, Stroustrup C++ 2. Ausgabe r.16.5 '#if constant-expression',' r.5.19 constant expression': "... Gleitende Konstanten müssen in ganzzahlige Typen umgewandelt werden". – denis

4

Ja.

Ich kann nicht glauben, dass noch niemand mit einem bestimmten verschleierten C-Contest-Gewinner verbunden ist. Der Typ implementierte eine ALU im Präprozessor über rekursive Includes. Here ist die Implementierung, und here ist so etwas wie eine Erklärung.

Nun, das sagte, Sie wollen nicht tun, was dieser Typ getan hat.Es macht Spaß und alles, aber schau dir die Kompilierzeiten in seiner Hinweisdatei an (ganz zu schweigen von der Tatsache, dass der resultierende Code nicht erreichbar ist). Häufiger verwenden Leute den Vorprozessor ausschließlich zum Ersetzen von Text, und die Auswertung von Konstanten mit konstanter Ganzzahl erfolgt entweder zur Kompilierungszeit oder zur Laufzeit.

Wie andere jedoch angemerkt haben, können Sie in #if-Anweisungen einige Arithmetik ausführen.

+1

http://stackoverflow.com/questions/652788/was-ist-the-worst-real-world-macros-pre-processor-abuse-youve-ever-come-across/1242177#1242177 - Chaos-pp . Präprozessor-Missbrauch mit Stil. –

6

Ja, es kann mit dem Boost Preprocessor durchgeführt werden. Und es ist kompatibel mit reinem C, so dass Sie es in C-Programmen mit nur C-Compilations verwenden können. Ihr Code bezieht sich auf Fließkommazahlen, ich denke also, dass dies indirekt geschehen muss.

#include <boost/preprocessor/arithmetic/div.hpp> 
BOOST_PP_DIV(11, 5) // expands to 2 
#define KB 1024 
#define HKB BOOST_PP_DIV(A,2) 
#define REM(A,B) BOOST_PP_SUB(A, BOOST_PP_MUL(B, BOOST_PP_DIV(A,B))) 
#define RKB REM(KB,2) 

int div = HKB; 
int rem = RKB; 

Diese vorverarbeitet, um (Überprüfung mit gcc -S)

int div = 512; 
int rem = 0; 

Dank this thread.

Verwandte Themen