Ci sono macchine dove sizeof (char)! = 1, o almeno CHAR_BIT> 8?


93

Ci sono macchine (o compilatori), dove sizeof(char) != 1?

Lo standard C99 dice che sizeof(char)l'implementazione della conformità allo standard DEVE essere esattamente 1? In caso affermativo, per favore, dammi il numero di sezione e la citazione.

Aggiornamento: se ho una macchina (CPU), che non può indirizzare i byte (la lettura minima è di 4 byte, allineata), ma solo 4-s di byte ( uint32_t), il compilatore per questa macchina può definire sizeof(char)a 4? sizeof(char)sarà 1, ma char avrà 32 bit ( CHAR_BITmacro)

Update2: Ma la dimensione del risultato NON è un BYTES! è la dimensione di CHAR. E il carattere può essere 2 byte o (può essere) 7 bit?

Update3: Ok. Tutte le macchine hanno sizeof(char) == 1. Ma quali macchine hanno CHAR_BIT > 8?


4
Sono preoccupato per la conformità allo standard C99. Lavoro a stretto contatto con i compilatori C99
osgx

2
Poiché Unicode diventa ancora più importante, potrebbero venire compilatori non standard che utilizzano caratteri Unicode come char(invece di wchar.) Anche se lo standard dice che sizeof(char)deve essere 1, non farei affidamento su questo presupposto.
Chip Uni

14
non ci sono compilatori C dove sizeof (char) non è 1, unicode o no.
nn.

6
@Chip: sizeof(char)è sempre 1, anche se char è a 32 bit (come accade su alcuni sistemi). C ha molte verruche divertenti.
Nick Bastin

2
Tutte le versioni dello standard C richiedono che CHAR_BIT sia almeno 8; non puoi avere CHAR_BIT == 7 ed essere conforme agli standard. Tuttavia, è perfettamente fattibile che le macchine abbiano CHAR_BIT> 8. Le vecchie macchine Cray lo avevano, credo ( sizeof(char) == sizeof(short) && sizeof(char) == sizeof(int)su quelle; non ricordo se sizeof(int) == sizeof(long)o se CHAR_BIT era 32 o 64; mi aspetto che fosse 32, e penso sizeof(long) == 1anche io . (Puoi trovare un riferimento, ma non l'accesso in linea, a un manuale di Cray C ).
Jonathan Leffler

Risposte:


91

È sempre uno in C99, sezione 6.5.3.4:

Quando applicato a un operando di tipo char, unsigned char o signed char (o una sua versione qualificata) il risultato è 1.

Modifica: non fa parte della tua domanda, ma per l'interesse di Harbison e Steele, 3a ed. (pre c99) p. 148:

Un'unità di memoria è considerata la quantità di memoria occupata da un carattere; la dimensione di un oggetto di tipo charè quindi 1.

Modifica: in risposta alla tua domanda aggiornata, la seguente domanda e risposta di Harbison e Steele è rilevante (ibid, Es. 4 del cap. 6):

È consentito avere un'implementazione C in cui il tipo charpuò rappresentare valori compresi tra -2.147.483.648 e 2.147.483.647? In caso affermativo, cosa ci sarebbe sizeof(char) in tale implementazione? Quali sarebbero le gamme di caratteri più piccole e più grandi int?

Risposta (ibid, p. 382):

È consentito (se dispendioso) per un'implementazione utilizzare 32 bit per rappresentare il tipo char. Indipendentemente dall'implementazione, il valore di sizeof(char)è sempre 1.

Anche se questo non riguarda specificamente un caso in cui, diciamo, i byte sono 8 bit e charsono 4 di quei byte (in realtà impossibile con la definizione c99, vedi sotto), il fatto che sizeof(char) = 1è sempre chiaro dallo standard c99 e da Harbison e Steele.

Modifica: In effetti (questo è in risposta alla tua domanda di aggiornamento 2), per quanto riguarda c99 sizeof(char) è in byte, dalla sezione 6.5.3.4 di nuovo:

L'operatore sizeof restituisce la dimensione (in byte) del suo operando

così combinato con la citazione sopra, byte di 8 bit e char4 di quei byte è impossibile: per c99 un byte è uguale a char.

In risposta alla tua menzione della possibilità di un 7 bit char: questo non è possibile in c99. Secondo la sezione 5.2.4.2.1 dello standard il minimo è 8:

I loro valori definiti dall'implementazione devono essere di grandezza uguale o maggiore [enfasi mia] a quelli indicati, con lo stesso segno.

- numero di bit per l'oggetto più piccolo che non è un campo di bit (byte)

 **CHAR_BIT 8**

- valore minimo per un oggetto di tipo signed char

**SCHAR_MIN -127//−(27−1)** 

- valore massimo per un oggetto di tipo signed char

**SCHAR_MAX +127//27−1** 

- valore massimo per un oggetto di tipo unsigned char

**UCHAR_MAX 255//28−1** 

- valore minimo per un oggetto di tipo char

**CHAR_MIN**    see below 

- valore massimo per un oggetto di tipo char

**CHAR_MAX**    see below

[...]

Se il valore di un oggetto di tipo char viene trattato come un numero intero con segno quando viene utilizzato in un'espressione, il valore di CHAR_MIN deve essere lo stesso di SCHAR_MIN e il valore di CHAR_MAX deve essere lo stesso di SCHAR_MAX. In caso contrario, il valore di CHAR_MIN sarà 0 e il valore di CHAR_MAX sarà lo stesso di UCHAR_MAX. Il valore UCHAR_MAX è uguale a 2 ^ CHAR_BIT - 1.


9
Nota aggiuntiva. c'è una macro CHAR_BITS che ti dirà quanti bit sono i tuoi caratteri.
nn.

1
I dati completi di questo grande libro sono di Harbison e Steele. C: A Reference Manual, terza edizione, Prentice Hall, 1991
osgx

2
Se sai che stai lavorando con i tipi di caratteri e sai che la lingua richiede che abbiano una dimensione di 1, perché è una buona idea mettere sempre la dimensione ridondante di (char)?

1
(a) e (c) hanno ramificazioni molto più serie che non possono sperare di risolvere, o addirittura avvicinarsi alla risoluzione; anche YAGNI. Qualcuno come in (b) deve solo essere detto una volta --- non ho bisogno di insegnargli in ogni riga del mio codice. Tuttavia, ci sono degli svantaggi nell'utilizzo sizeof(char): è un altro elemento da discutere / controllare / ecc. nelle tue convenzioni / standard / linee guida di codifica, spreco il mio tempo a chiedermi se conosci davvero C e cos'altro potrebbe essere sbagliato, occupa la "larghezza di banda" visiva / mentale / di testo.

1
@ Ramashalanka: Sì, il codice compilato è equivalente. Sono tutte le questioni relative alla leggibilità e al modo in cui le persone usano il codice sorgente di cui sto parlando. (E FWIW, penso che tu abbia una risposta +1 decente qui, trovo solo che "usa sempre sizeof (char)" sia fuorviante e un problema di hotbutton per me, anche se un piccolo problema.)

21

Non ci sono macchine dove sizeof(char)è 4. È sempre 1 byte. Quel byte potrebbe contenere 32 bit, ma per quanto riguarda il compilatore C, è un byte. Per maggiori dettagli, in realtà ti indicherò le domande frequenti su C ++ 26.6 . Quel collegamento lo copre abbastanza bene e sono abbastanza certo che C ++ abbia ottenuto tutte queste regole da C. Puoi anche guardare la FAQ 8.10 di comp.lang.c per i caratteri più grandi di 8 bit.

Upd2: Ma la dimensione del risultato NON è un BYTES! è la dimensione di CHAR. E il carattere può essere 2 byte o (può essere) 7 bit?

Sì, sono byte. Lasciatemelo dire di nuovo. sizeof(char)è 1 byte secondo il compilatore C. Ciò che le persone chiamano colloquialmente un byte (8 bit) non è necessariamente lo stesso di ciò che il compilatore C chiama un byte. Il numero di bit in un byte C varia a seconda dell'architettura della macchina. È inoltre garantito che sia almeno 8.


3
Per favore!!! Il C ++ è il linguaggio veramente DIVERSO dal C (C99). Questa domanda riguarda solo il C normale.
osgx

<strike> Cosa posso fare quando la macchina / CPU non può accedere ai byte a 8 bit? L'accesso non allineato è proibito. </strike> (Anche su x86 malloc restituisce dati allineati e alloca memoria in multipli di 4 byte.) <strike> Quindi CHAT_BIT sarà maggiore di 8. Sì, tale piattaforma può essere piuttosto speciale. </ Strike >
osgx

10
@osgx, tendo a urlare tanto quanto hai appena fatto quando le persone cercano di mescolare C e C ++. Ma penso che in questo caso una voce delle domande frequenti in C ++ si applichi altrettanto bene a C.
Michael Kristofik

3
Il nome corretto per "8 bit" è ottetto. Lo standard C utilizza la parola "byte" per un oggetto che ha le dimensioni di un carattere. Altri possono usare la parola "byte" in modi diversi, spesso quando significano "ottetto", ma in C (e C ++, o Objective-C) significa "oggetto della dimensione di un carattere". Un carattere può contenere più di 8 bit o più di un ottetto, ma è sempre un byte.
gnasher729

9

PDP-10 e PDP-11 erano.

Aggiornamento: non esistono compilatori C99 per PDP-10.

Alcuni modelli di DSP SHARC a 32 bit di Analog Devices hanno CHAR_BIT = 32 e il DSP Texas Instruments da TMS32F28xx ha CHAR_BIT = 16, secondo quanto riferito .

Aggiornamento: c'è GCC 3.2 per PDP-10 con CHAR_BIT = 9 (controlla include / limits.h in quell'archivio).


1
Non confondere le implementazioni di linguaggi simili ma non C a C. Hai anche detto "Sono preoccupato per la conformità allo standard C99. Lavoro a stretto contatto con i compilatori C99".

2
@Roger: Non è giusto definire GCC3 non conforme a C99 a meno che non si tratti di casi limite estremi che sono considerati bug in GCC.
Joshua,

1
@ Joshua, penso che Roger dica dei compilatori storici K&R e pcc. Inoltre non è giusto affermare che è conforme a C99 prima che la suite di test di conformità C99 venga eseguita su PDP-10, quando compilata con questa porta (possono esserci bug dal porting e dalla macchina stessa). Ma ci si può aspettare che sia vicino allo standard C99 come GCC3.2 su x86.
osgx

1
@Joshua: CHAR_BIT può essere maggiore di 8, in C99, ma sizeof (char) deve essere ancora 1 (e questa risposta era molto diversa quando ho lasciato quel commento). Non sto chiamando GCC3 non conforme e C89 richiede lo stesso requisito qui, BTW. Ho citato quel testo per dire che osgx è quello preoccupato per la conformità C99 e utilizza compilatori C99, quindi perché è preoccupato per i compilatori non C99?

2
Autore di PDP-10 GCC qui. CHAR_BIT è 9, ma sizeof (char) è ancora 1.
Lars Brinkhoff
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.