2011-02-02 12 views
9

GCC supporta -fshort-wchar che passa da wchar_t a 4 byte.Quanto è grande wchar_t con GCC?

Qual è il modo migliore per rilevare la dimensione di wchar_t in fase di compilazione, così posso mapparlo correttamente al tipo utf-16 o utf-32 appropriato? Almeno, fino a quando C++ 0x viene rilasciato e ci fornisce utf16_t e utf_32_t typedefs stabili.

#if ?what_goes_here? 
    typedef wchar_t Utf32; 
    typedef unsigned short Utf16; 
#else 
    typedef wchar_t Utf16; 
    typedef unsigned int Utf32; 
#endif 
+2

non fare questo. wchar_t non ha nulla a che fare con unicode. È un tipo distinto che può contenere tutti i membri del set di caratteri esteso più grande di tutte le impostazioni locali supportate. Se la tua piattaforma supporta solo ASCII allora sizeof (wchar_t) può essere 1. Ciò significa anche che, ad esempio, L'mötley crüe 'è * non necessariamente * una stringa unicode - potrebbe anche essere una stringa Latin-1 memorizzata con wchar_t. –

+6

Questo è il commento più universalmente inutile di sempre. Sulla base di tale consiglio, non dovremmo mai tentare di trattare una stringa codificata in Utf finché C++ 0x non viene rilasciato universalmente. Nel frattempo, ho bisogno di un set di typedefs, per le piattaforme che supporto, che mappino ai tipi distinti più appropriati in grado di contenere i dati richiesti. –

risposta

8

È possibile utilizzare le macro

__WCHAR_MAX__ 
__WCHAR_TYPE__ 

sono definiti da gcc. È possibile controllare il loro valore con echo "" | gcc -E - -dM

Poiché il valore di __WCHAR_TYPE__ può variare da int a short unsigned int o long int, la migliore per il tuo test è IMHO per verificare se __WCHAR_MAX__ è superiore al 2^16.

#if __WCHAR_MAX__ > 0x10000 
    typedef ... 
#endif 
+0

Im contrassegnare questo come la risposta, in quanto è il più vicino a quello che stavo cercando. Il modello magico nell'altra risposta sembra un modo ancora più intelligente per supportare più piattaforme senza conoscere molte macro specifiche della piattaforma –

10
template<int> 
struct blah; 

template<> 
struct blah<4> { 
    typedef wchar_t Utf32; 
    typedef unsigned short Utf16; 
}; 

template<> 
struct blah<2> { 
    typedef wchar_t Utf16; 
    typedef unsigned int Utf32; 
}; 

typedef blah<sizeof(wchar_t)>::Utf16 Utf16; 
typedef blah<sizeof(wchar_t)>::Utf32 Utf32; 
+1

+1. Lo chiamerei 'struct utf_types' però :) –

+1

Perché dovresti dare per scontato che un corto senza segno sia largo 2 byte e un int unsigned di 4 byte, e quindi non li digiti semplicemente incondizionatamente? Stai usando le tue supposizioni con disinvoltura ... – etarion

+0

@etarion: ho semplicemente risposto alla domanda. Wchar_t è un tipo distinto in C++ (non posso richiamarlo per C) e l'OP (apparentemente) vuole usarlo. –

2

Come detto Blissett, wchar_t esiste indipendentemente da Unicode - sono due cose diverse.

Se si parla veramente di UTF-16, sii consapevole che esistono caratteri unicode che mappano a due parole a 16 bit (U + 10000..U + 10FFFF, anche se questi sono usati raramente in paesi/lingue occidentali) .

2

È possibile utilizzare la macro standard: WCHAR_MAX:

#include <wchar.h> 
#if WCHAR_MAX > 0xFFFFu 
// ... 
#endif 

WCHAR_MAX Macro è stato definito da ISO C e ISO C++ standard (vedere: ISO/IEC 9899 - 7.18.3 Limiti di altri integer tipi e ISO/IEC 14882 - C.2), quindi è possibile utilizzarlo in sicurezza su quasi tutti i compilatori.

1
$ g++ -E -dD -xc++ /dev/null | grep WCHAR 
#define __WCHAR_TYPE__ int 
#define __WCHAR_MAX__ 2147483647 
#define __WCHAR_MIN__ (-__WCHAR_MAX__ - 1) 
#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2 
#define __SIZEOF_WCHAR_T__ 4 
0

La dimensione dipende dal compilatore bandierina -fshort-wchar:

g++ -E -dD -fshort-wchar -xc++ /dev/null | grep WCHAR 
#define __WCHAR_TYPE__ short unsigned int 
#define __WCHAR_MAX__ 0xffff 
#define __WCHAR_MIN__ 0 
#define __WCHAR_UNSIGNED__ 1 
#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2 
#define __SIZEOF_WCHAR_T__ 2 
#define __ARM_SIZEOF_WCHAR_T 4