2015-06-15 50 views
10

In base a the C standard, tutti i caratteri restituiti da fgetc vengono restituiti sotto forma di valori unsigned char, "convertiti in un int" (quella citazione proviene dallo standard C, affermando che esiste effettivamente una conversione).Un'implementazione che ha sizeof (int) == 1 "completamente conforme"?

Quando sizeof (int) == 1, molti valori unsigned char non rientrano nell'intervallo. È quindi possibile che alcuni di questi valori unsigned char possano essere convertiti in un valore int (il risultato della conversione è "implementation-defined or an implementation-defined signal is raised") di EOF, che verrebbe restituito nonostante il file non sia effettivamente in un file errato o di fine file stato.

Sono stato sorpreso di scoprire che tale implementazione esiste realmente. Il TMS320C55x CCS manual documenti UCHAR_MAX con un valore corrispondente di 65535, INT_MAX con 32767, fputs e fopen che supporta la modalità binaria ... Ciò che è ancora più sorprendente è che sembra descrivere l'ambiente come un'implementazione completa e completamente conforme (segnali meno).

Il C55x C/C++ è pienamente conforme allo standard ISO C, come definito dalle specifiche ISO ...

Il compilatore strumenti sono dotati di una completa libreria di runtime. Tutte le funzioni della libreria sono conformi allo standard di libreria ISO C. ...

è una tale implementazione in grado di restituire un valore che indica gli errori in cui non ce ne sono, in realtà pienamente conforme? Questo potrebbe giustificare l'uso di feof e ferror nella sezione delle condizioni di un loop (per quanto orribile possa sembrare)? Ad esempio, while ((c = fgetc(stdin)) != EOF || !(feof(stdin) || ferror(stdin))) { ... }

+3

@BLUEPIXY Un "byte" in standardese è qualunque sia un 'char'. Non è necessariamente 8 bit. –

+0

Sono confuso, se 'sizeof (int)' è '1', come mai' INT_MAX' è '32767'? quel valore richiede due byte da 8 bit. E infatti, un byte potrebbe essere più di 8 bit, quindi la macro 'CHAR_BIT' è usata per determinarlo. –

+3

@iharob Questo sistema non usa byte a 8 bit. – duskwuff

risposta

2

La funzione fgetc() restituisce un valore int nell'intervallo unsigned char solo quando un carattere proprio viene letto, altrimenti restituisce EOF che è un valore negativo di tipo int.

mia risposta originale (ho cambiato) assume che vi era una conversione intero a int, ma questo non è il caso, dato che in realtà la funzione fgetc() è già restituisce un valore di tipo int.

penso che, per essere conforme, l'attuazione deve fare fgetc() per restituire valori non negativi nella gamma di int, a meno che EOF viene restituito.

In questo modo, l'intervallo di valori da 32768 a 65535 non verrà mai associato ai codici carattere nell'implementazione del TMS320C55x.

+0

Puntelli per vedere il problema qui. Quella particolare implementazione potrebbe violare il contratto di 'fgetc' o restituendo un valore negativo quando non dovrebbe, o non supportando correttamente i file binari ... – Sebivor