Ich möchte ein Makro definieren, wenn eine Bedingung involviert ist sizeof wahr ist und nichts tut (aber dennoch kompiliert), wenn es falsch ist. Wenn der Präprozessor unterstützt sizeofdas sähe so aus:
… Und was genau wollen Sie anders machen, je nachdem, ob Zeiger in uints passen? Was auch immer es ist, es ist normalerweise eine schlechte Idee….
– Karl Knechtel
7. Dezember 2010 um 8:01 Uhr
Übergeben Sie die Zeiger an einen anderen Prozess, der später in die Bibliothek zurückruft (und unsigned int können direkt übergeben werden, während 64-Bit-Typen selbst als Zeiger übergeben werden müssen).
– Alexej Romanow
7. Dezember 2010 um 8:22 Uhr
Nein, tun sie nicht. Sie können einen 64-Bit-Wert auf herkömmliche Weise übergeben – selbst wenn Sie für 32 Bit kompilieren (was Sie wahrscheinlich nicht sind, wenn Ihre Zeiger 64 Bit sind).
Was ist falsch daran, immer zu verwenden intptr_t?
– Christoph Creutzig
8. Dezember 2010 um 12:26 Uhr
Du kannst es einfach nicht. sizeof ist ein Kompilierzeitoperator. #if und #define und Präprozessor bezogen. Da der Präprozessor VOR dem Compiler läuft, funktioniert dies einfach nicht. Möglicherweise finden Sie jedoch einen geheimen Compiler-Schalter, mit dem Sie ihn mehrfach übergeben können (dh vorverarbeiten, vorgeben, kompilieren, vorverarbeiten, kompilieren), aber fairerweise würde ich es aufgeben, zu versuchen, das zu tun, was Sie wollen. Es soll nicht funktionieren und tut es einfach nicht.
Am besten setzen Sie solche Definitionen als -D-Befehle, die an den Compiler übergeben werden. Sie können statisch behaupten, dass die ausgewählten korrekt sind. Auf diese Weise müssen Sie nur ein paar Definitionen extern für einen bestimmten Kompilierungsmodus (z. B. PowerPC-Release) und so weiter einrichten.
Das Beste Der Ansatz besteht darin, Ihr Build-System (Autotools usw.) zu verwenden, um Prüfungen durchzuführen und eine systemkonfigurierte Datei damit zu erstellen #define SIZEOF_POINTER 4 oder was auch immer, und das dann verwenden.
– Chris Lutz
7. Dezember 2010 um 7:58 Uhr
Es ist erwähnenswert, dass in C11 _Static_assert wird erreichen, was OP will.
– Tschad
18. August 2016 um 21:07 Uhr
Jonathan Leffler
Die richtige Lösung für Ihr Problem ist die Verwendung der C99-Standardheader:
#include <stdint.h>
#include <inttypes.h>
Da braucht man nur eines von beiden #include <inttypes.h> enthält das Material von #include <stdint.h>; jedoch viel Material drin <inttypes.h> ist nur relevant für formatierte I/O mit scanf() und printf().
Das ist der vorzeichenlose Integer-Typ, der groß genug ist, um jeden Zeiger aufzunehmen (d. h. jeden Datenzeiger im C-Standard; POSIX erlegt eine zusätzliche Regel auf, dass er auch groß genug sein muss, um auch Funktionszeiger aufzunehmen). Der Typ uintptr_t ist darin definiert <stdint.h>.
Wenn Sie später solche Werte oder Rohzeiger drucken, können Sie die Informationen aus verwenden <inttypes.h>:
Wenn pred zu 0 ausgewertet wird, wie es ein falscher boolescher Ausdruck in C tut, gibt der Compiler einen Fehler aus.
+1. Ich habe etwas Ähnliches verwendet, um ein Array mit der Größe 0 oder -1 zu deklarieren (-1 verursacht einen Kompilierungsfehler), aber ich denke, die Verwendung von switch ist ordentlicher.
was impliziert sizeof (void *) <= sizeof (intptr_t) <= sizeof (int) auf jede vernünftige Implementierung der C-Sprache.
stewori
Angesichts der Tatsache, dass die anderen Antworten bereits erklärt haben, warum sizeof kann nicht mit verwendet werden #if, lassen Sie mich eine einfache Lösung für Ihren Fall anbieten (überraschenderweise noch nicht erwähnt). Schauen Sie sich an
Es erwähnt mehrere vordefinierte __SIZEOF_XYZ__ Makros, die tatsächlich in der Vorverarbeitungsphase verwendet werden können, dh auch in #if. Vorausgesetzt unsigned int und int gleich groß sind, kann Ihr Beispiel so aussehen:
Obwohl die Frage eher mit C als mit C++ gekennzeichnet ist, ist es möglicherweise hilfreich zu wissen, dass C++0x einen Mechanismus für statische Zusicherungen definiert, die vom Compiler und nicht vom Präprozessor überprüft werden.
Aus values.h : #define _TYPEBITS(type) (sizeof (type) * CHAR_BIT) #define INTBITS _TYPEBITS (int) #define PTRBITS _TYPEBITS (char *) Ich weiß nicht, wo CHAR_BIT gesetzt ist, aber INTBITS und PTRBITS sind immer noch sizeof Ausdrücke.
– Oper
7. Dezember 2010 um 8:08 Uhr
@Opera: Es bedeutet nur, dass INTBITS usw. nicht vom Präprozessor analysiert werden können. Die Makros können nicht in a verwendet werden #if oder ähnliche Aussage. Die Makros können im eigentlichen Code erscheinen, aber nicht in Präprozessordirektiven.
… Und was genau wollen Sie anders machen, je nachdem, ob Zeiger in uints passen? Was auch immer es ist, es ist normalerweise eine schlechte Idee….
– Karl Knechtel
7. Dezember 2010 um 8:01 Uhr
Übergeben Sie die Zeiger an einen anderen Prozess, der später in die Bibliothek zurückruft (und
unsigned int
können direkt übergeben werden, während 64-Bit-Typen selbst als Zeiger übergeben werden müssen).– Alexej Romanow
7. Dezember 2010 um 8:22 Uhr
Nein, tun sie nicht. Sie können einen 64-Bit-Wert auf herkömmliche Weise übergeben – selbst wenn Sie für 32 Bit kompilieren (was Sie wahrscheinlich nicht sind, wenn Ihre Zeiger 64 Bit sind).
– JeremyP
7. Dezember 2010 um 10:05 Uhr
Ja, in diesem Fall tun sie das: siehe Tabelle in erlang.org/doc/man/erl_driver.html#driver_output_term
– Alexej Romanow
7. Dezember 2010 um 10:40 Uhr
Was ist falsch daran, immer zu verwenden
intptr_t
?– Christoph Creutzig
8. Dezember 2010 um 12:26 Uhr