2009-02-14 10 views
14

Sto lavorando con framework di Apple ScriptingBridge, e hanno generato un file di intestazione per iTunes che contiene diversi enum s come questo:Qual è il tipo di enum i cui valori sembrano essere stringhe?

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

La mia comprensione era che enum valori dovevano essere intero simile, ma questa definizione sembra per violare questa regola. Inoltre, sembra che il trattamento di questi valori enum come numeri interi (in un NSPredicate, ad esempio) non faccia la cosa giusta.

ho aggiunto dichiarazione enum sopra in un file C con una funzione vuota main, e compilati utilizzando i686-apple-darwin9-gcc-4.0.1. Quindi, mentre questi tipi di enum s potrebbero non essere conformi allo standard C (come indica Parappa di seguito), sono almeno compilati allo del tipo da gcc.

Quindi, qual è il tipo e come posso utilizzarlo, ad esempio, in una stringa di formato?

risposta

18

C99, TC3 legge:

6.4.4.4 §2:

Una costante carattere intero è una sequenza di uno o più caratteri multibyte racchiuso tra virgolette singole, come in 'x '. [...]

6.4.4.4 § 10:

Un numero intero costante personaggio ha tipo int. Il valore di una costante di carattere intero contenente un singolo carattere mappato a un carattere di esecuzione a byte singolo è il valore numerico della rappresentazione del carattere mappato interpretato come un numero intero. Il valore di una costante di carattere intero contenente più di un carattere (ad es. 'Ab') o contenente un carattere o una sequenza di escape che non è mappata su un carattere di esecuzione a byte singolo, è definito dall'implementazione. Se una costante di carattere intero contiene un singolo carattere o sequenza di escape, il suo valore è quello che risulta quando un oggetto con tipo char il cui valore è quello del singolo carattere o sequenza di escape viene convertito in tipo int.

Nella maggior parte delle implementazioni, è sicuro da usare costanti carattere interi di un massimo di 4 caratteri a un byte. Tuttavia, il valore effettivo potrebbe differire tra i diversi sistemi (endianness?).


Questo è in realtà già definito nello standard ANSI-C89, sezione 3.1.3.4:

Una costante carattere intero è una sequenza di uno o più caratteri multibyte racchiuso tra apostrofi, come in 'x' o 'ab'. [...]

Una costante di carattere intero ha tipo int. Il valore di una costante di carattere intero contenente un singolo carattere che associa in un membro del set di caratteri di esecuzione di base è il valore numerico della rappresentazione del carattere mappato interpretato come numero intero . Il valore di una costante di carattere intero contenente più di un carattere o contenente un carattere o sequenza di escape non rappresentata nel set di caratteri di esecuzione di base, è definito dall'implementazione . In particolare, in un'implementazione in cui il tipo di carattere ha lo stesso intervallo di valori del carattere firmato, la posizione di ordine elevato di una costante di carattere intero di carattere singolo è trattata come un bit di segno.

+0

Buono - qualcosa di ufficiale. :) –

+0

Questa era un'estensione comune, ma non portatile, non standard prima del c99. – dmckee

+1

@dmckee: costanti di caratteri multi-byte erano già parte di ANSI-C89 (vedi paragrafo 3.1.3.4), così è sempre stato normale! – Christoph

6

Le virgolette singole indicano i caratteri anziché le stringhe in C. Quindi ciascuna delle enumerazioni avrà un valore di 32 bit costituito dai codici di carattere per i quattro caratteri. Il valore effettivo dipenderà dalle codifiche dei caratteri, ma sto assumendo caratteri a 8 bit. Nota: no aggiunto \ 0.

È possibile utilizzare l'enumerazione per i normali scopi di confronto/assegnazione. Come per ogni enumerazione, il tipo sottostante è intero.

Ho usato questa tecnica in sistemi embedded molte volte per creare 4 nomi di caratteri che erano leggibili da umani in contesti esadecimale/debugger.

0

Che è un'estensione di Apple a C, che Si traduce in pratica quei enumerazioni a:

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

EDIT: Scusate, a quanto pare è valida C. li ho sembrano solo nel codice Mac, così a torto supponevo che fosse specifico di Apple.

+0

no, è valido ISO-C! – Christoph

+0

Non è solo un'estensione Apple. L'ho usato in diversi compilatori C e ARM, sec 2.5.2 indica che è C++ valido. Non avere una specifica C a portata di mano. Ma hai ragione riguardo all'interpretazione del valore, in genere. Ufficialmente dipende dall'implementazione. –

+0

Grazie, non sapevo, gcc in Linux lo avverte comunque. – codelogic

2

Come già detto, questi sono numeri interi dichiarati utilizzando costanti di carattere.

Quando un intero viene dichiarato utilizzando una costante di carattere di più di un carattere, è sensibile allo byte order della macchina per la quale è stata sviluppata la costante. Poiché tutte le API Mac originali erano su PPC o su macchine precedenti, sono retrocompe rispetto alle macchine Intel Little-Endian.

Se stai solo costruendo per Intel puoi semplicemente invertire l'ordine a mano.

Se si sta creando un binario universale, è necessario utilizzare uno flipping function come CFSwapInt32BigToHost.

La mancata correzione di quei codici vi lascerà con un codice che potrebbe funzionare solo su macchine PowerPC, indipendentemente dalla mancanza di errori del compilatore.

Problemi correlati