2011-02-02 27 views
9

GCC admite -fshort-wchar que cambia wchar_t de 4 a dos bytes.¿Qué tan grande es wchar_t con GCC?

¿Cuál es la mejor forma de detectar el tamaño de wchar_t en tiempo de compilación, por lo que puedo asignarlo correctamente al tipo apropiado utf-16 o utf-32? Al menos, hasta que se libere C++ 0x y nos proporcione utf16_t y utf_32_t typedefs estables.

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

No haga esto. wchar_t no tiene nada que ver con unicode. Es un tipo distinto que puede contener todos los miembros del conjunto de caracteres ampliado más grande de todas las configuraciones regionales compatibles. Si su plataforma solo admite ASCII, sizeof (wchar_t) puede ser 1. Esto también significa que, por ejemplo, que L'mötley crüe 'no es * necesariamente una cadena unicode, podría ser una cadena Latin-1 almacenada con wchar_t. –

+6

Ese es el comentario más universalmente inútil de la historia. Sobre la base de ese consejo, nunca deberíamos intentar tratar con una cadena codificada Utf hasta que C++ 0x sea lanzado universalmente. Mientras tanto, necesito un conjunto de typedefs, para las plataformas que soporto, que se correlacionan con los tipos distintivos más apropiados que pueden contener los datos requeridos. –

Respuesta

8

Puede utilizar las macros

__WCHAR_MAX__ 
__WCHAR_TYPE__ 

Se definen por gcc. Puede comprobar su valor con echo "" | gcc -E - -dM

A medida que el valor de __WCHAR_TYPE__ puede variar de int a short unsigned int o long int, lo mejor para su prueba es mi humilde opinión, para comprobar si __WCHAR_MAX__ es superior a 2^16.

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

Im marcado esto como la respuesta, ya que es el más cercano a lo que estaba buscando. La magia de la plantilla en la otra respuesta parece una forma aún más inteligente de admitir más plataformas sin saber muchas macros específicas de la plataforma –

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. Yo lo llamaría 'struct utf_types' aunque :) –

+1

¿Por qué supondrías que un corto sin signo tiene 2 bytes de ancho y un int sin firmar de 4 bytes, y luego no simplemente los escribe sin condiciones? Estás usando tus suposiciones a medias ... – etarion

+0

@etarion: Simplemente respondí la pregunta. Wchar_t es un tipo distinto en C++ (no recuerdo para C) y OP (aparentemente) quiere usarlo. –

2

Como dijo Luther Blissett, existe wchar_t independientemente de Unicode - son dos cosas diferentes.

Si realmente está hablando de UTF-16, tenga en cuenta que hay caracteres unicode que se correlacionan con dos palabras de 16 bits (U + 10000..U + 10FFFF, aunque éstas se usan raramente en países/idiomas occidentales) .

2

Puede utilizar la macro estándar: WCHAR_MAX:

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

WCHAR_MAX Macro fue definida por ISO C y ISO C++ estándar (véase: ISO/IEC 9899 - 7.18.3 límites de otro número entero tipos y ISO/IEC 14882 - C.2), por lo que podría usarlo de forma segura en casi todos los compiladores.

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

El tamaño depende de la bandera compilador -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 
Cuestiones relacionadas