2009-08-02 7 views
7

C'è un modo per fare qualcosa di simile in C++, sembra che le dimensioni non possano essere usate lì per qualche motivo?C++ Ottenere le dimensioni di un tipo in una macro condizionale

#if sizeof(wchar_t) != 2 
#error "wchar_t is expected to be a 16 bit type." 
#endif 
+0

Ho appreso che le affermazioni in fase di costruzione sono possibili, grazie alla tua domanda. Questa tecnica è discussa in dettaglio in questo thread: http://stackoverflow.com/questions/174356/ways-to-assert-expressions-at-build-time-in-c – nagul

risposta

14

No, questo non può essere fatto perché tutti macro di espansione (# ... cose) viene fatto nella fase di pre-processore che non sa nulla circa i tipi di codice C++ e anche se non lo fa bisogno di sapere qualcosa sulla lingua! Espande/controlla solo le # ... cose e nient'altro!

ci sono alcuni altri errori comuni, ad esempio:

enum XY 
{ 
    MY_CONST = 7, 
}; 

#if MY_CONST == 7 
    // This code will NEVER be compiled because the pre-processor does not know anything about your enum! 
#endif // 

È possibile solo accedere e utilizzare le cose in #if che sono definiti tramite le opzioni della riga di comando per il compilatore o tramite #define.

+0

Al giorno d'oggi, il preposore non esiste a volte. –

+0

@Cole Johnson: non vedo mai nessuno che ometta completamente il pre-processore. Conosci qualche compilatore C o C++ senza un pre-processore? – mmmmmmmm

+0

Non che io sappia.Mi riferivo a cose come '# pragma' –

3

sizeof() è un runtime funzione di compilazione. Non puoi chiamarlo in una direttiva preprocessore. Non penso che sia possibile controllare la dimensione di wchar_t durante la pre-elaborazione. (vedi Edit 2)

Edit: Come sottolineato nei commenti, sizeof() è in gran parte calcolato al momento della compilazione. In C99, it can be used at runtime for arrays.

Modifica 2: è possibile eseguire attività di supporto in fase di compilazione utilizzando le tecniche descritte in questo thread.

+7

sizeof() NON è una funzione di runtime. È un'espressione in fase di compilazione che viene valutata dal compilatore in fase di compilazione (ma dopo il tempo di pre-elaborazione). – mmmmmmmm

+0

Grazie, non ne ero a conoscenza. Aggiornato di conseguenza. – nagul

+1

@nagul: Ok, forse non sempre un'espressione in fase di compilazione :-) – mmmmmmmm

7

Il preprocessore funziona senza sapere nulla dei tipi, anche quello incorporato.

BTW, è ancora possibile eseguire il controllo utilizzando una funzione static_assert come (boost ne ha uno per esempio, C++ 0X ne avrà uno).

Edit: C99 e C++ 0x hanno anche WCHAR_MIN e WCHAR_MAX macro in <stdint.h>

1
char _assert_wchar_t_is_16bit[ sizeof(wchar_t) == 2 ? 1 : -1]; 
3

Non si ottiene sostanzialmente ciò che si desidera (errore di compilazione senza il messaggio di fantasia) utilizzando un C_ASSERT?

#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1] 
0

Ho sviluppato alcune macro che consentono effettivamente di utilizzare sizeof all'interno di una condizione macro. Sono in un file di intestazione che ho caricato here (licenza MIT).

Esso consentirà di codice come questo:

#include <iostream> 
#include "SIZEOF_definitions.h" 

//You can also use SIZEOF_UINT in place of SIZEOF(unsigned, int) 
// and UINT_BIT in place of SIZEOF_BIT(unsigned, int) 
#if SIZEOF(unsigned, int) == 4 
int func() { return SIZEOF_BIT(unsigned, int); } 
#elif SIZEOF(unsigned, int) == 8 
int func() { return 2 * SIZEOF_BIT(unsigned, int); } 
#endif 

int main(int argc, char** argv) { 
    std::cout SIZEOF(unsigned, long, int) << " chars, #bits = " << SIZEOF_BIT(unsigned, long, int) << '\n' 
     << SIZEOF(unsigned, int)  << " chars, #bits = " << SIZEOF_BIT(unsigned, int)  << '\n' 
     << SIZEOF(int)     << " chars, #bits = " << SIZEOF_BIT(int)     << '\n'; 
    std::cout << func() << std::endl; 
    return 0; 
} 

Nota le virgole all'interno SIZEOF(unsigned, long, int).

Problemi correlati