2009-02-14 6 views
14

estoy trabajando con marco de Apple ScriptingBridge, y han generado un archivo de cabecera para iTunes que contiene varios enum s como este:¿Cuál es el tipo de una enumeración cuyos valores parecen ser cadenas?

typedef enum { 
    iTunesESrcLibrary = 'kLib', 
    iTunesESrcIPod = 'kPod', 
    iTunesESrcAudioCD = 'kACD', 
    iTunesESrcMP3CD = 'kMCD', 
    iTunesESrcDevice = 'kDev', 
    iTunesESrcRadioTuner = 'kTun', 
    iTunesESrcSharedLibrary = 'kShd', 
    iTunesESrcUnknown = 'kUnk' 
} iTunesESrc; 

Mi entendimiento es que enum valores tenían que ser entero-como, pero esta definición parece violar esa regla. Además, parece que tratar estos valores enum como enteros (en un NSPredicate, por ejemplo) no hace lo correcto.

Agregué la declaración enum anterior a un archivo C con una función main vacía, y se compiló usando i686-apple-darwin9-gcc-4.0.1. Por lo tanto, aunque este tipo de enum s puede no ajustarse al estándar C (como señala Parappa a continuación), al menos se compilan en algunos tipo por gcc.

Entonces, ¿qué es ese tipo y cómo puedo usarlo, por ejemplo, en una cadena de formato?

Respuesta

18

C99, TC3 lee:

6.4.4.4 § 2:

Una constante de caracteres número entero es una secuencia de uno o más caracteres multibyte encerrado en comillas simples, como en 'x '. [...]

6.4.4.4 §10:

una constante entera personaje tiene tipo int. El valor de una constante de caracteres enteros que contiene un solo carácter que se asigna a un carácter de ejecución de un solo byte es el valor numérico de la representación del carácter correlacionado interpretado como un entero. El valor de una constante de caracteres enteros que contiene más de un carácter (por ejemplo, 'ab'), o que contiene un carácter o secuencia de escape que no se correlaciona con un carácter de ejecución de un solo byte, está definido por la implementación. Si una constante de caracteres enteros contiene un único carácter o secuencia de escape, su valor es el que resulta cuando un objeto con tipo char cuyo valor es el del carácter único o secuencia de escape se convierte en tipo int.

En la mayoría de las implementaciones, es seguro usar constantes de caracteres enteros de hasta 4 caracteres de un byte. El valor real puede diferir entre los diferentes sistemas (endianness?) Sin embargo.


Esto es en realidad ya definido en el estándar ANSI-C89, sección 3.1.3.4:

Una constante de carácter entero es una secuencia de uno o más caracteres de varios bytes encerrado en comillas simples, como en 'x' o 'ab'. [...]

Una constante de caracteres enteros tiene tipo int. El valor de una constante de caracteres enteros que contiene un solo carácter que mapea en un miembro del juego de caracteres de ejecución básico es el valor numérico de la representación del carácter correlacionado interpretado como un entero . El valor de una constante de caracteres enteros que contiene más que un carácter, o que contiene un carácter o secuencia de escape no representada en el conjunto de caracteres de ejecución básica, es definido por la implementación. En particular, en una implementación en la cual tipo char tiene el mismo rango de valores que el signo char, la posición de bits de alto orden de una constante de caracteres enteros de un solo carácter es tratada como un bit de signo.

+0

Bueno, algo oficial. :) –

+0

Esta era una extensión común, pero no portátil, no estándar antes de c99, también. – dmckee

+1

@dmckee: las constantes de caracteres multi-byte ya eran parte de ANSI-C89 (ver sección 3.1.3.4), ¡así que siempre ha sido estándar! – Christoph

6

Las comillas simples indican caracteres, en lugar de cadenas en C. Por lo tanto, cada una de las enumeraciones tendrá un valor de 32 bits que constará de los códigos de los caracteres de los cuatro caracteres. El valor real dependerá de las codificaciones de caracteres, pero asumo caracteres de 8 bits. Tenga en cuenta que hay no anexado \ 0.

Puede usar las enumeraciones para propósitos normales de comparación/asignación. Como con cualquier enumeración, el tipo subyacente es entero.

He usado esta técnica en sistemas embebidos muchas veces para crear 4 nombres de caracteres legibles por humanos en contextos de volcado hexadecimal/depurador.

0

Eso es una extensión de Apple a C, lo que se traduce Básicamente esas enumeraciones a:

typedef enum { 
    iTunesESrcLibrary = 'k'<<24 | 'L'<<16 | 'i'<<8 | 'b', 
... 
} 

EDIT: Lo siento, al parecer es C. válida sólo he parece que en el código de Mac, por lo que erróneamente asumió que era específico de Apple.

+0

no, ¡es válido ISO-C! – Christoph

+0

No es simplemente una extensión de Apple. Lo he usado en varios compiladores de C y el ARM, sec 2.5.2 indica que es C++ válido. No tiene una especificación C a mano. Pero tiene razón acerca de la interpretación del valor, por lo general. Oficialmente depende de la implementación. –

+0

Gracias, no estaba enterado, gcc en Linux sí lo advierte. – codelogic

2

Como ya se ha indicado, esos son enteros declarados con constantes de caracteres.

Cuando se declara un número entero utilizando una constante de carácter de más de un carácter, es sensible al byte order de la máquina para la que se desarrolló la constante. Como todas las API Mac originales estaban en PPC o máquinas anteriores, están rezagadas con respecto a las máquinas Intel Little-Endian.

Si solo está construyendo para Intel, puede simplemente invertir el orden a mano.

Si está construyendo un binario universal, necesita usar un flipping function como CFSwapInt32BigToHost.

Si no corrige esos códigos, obtendrá un código que solo podría funcionar en máquinas PowerPC, independientemente de la falta de errores del compilador.

Cuestiones relacionadas