41 votes

Peut sizeof (int) jamais être 1 sur une implémentation hébergée?

De mon point de vue est qu'une œuvre ne peut pas satisfaire à la spécification de certains stdio fonctions (en particulier fputc/fgetc) si sizeof(int)==1, depuis l' int doit être capable de tenir toute valeur possible de unsigned char ou EOF (-1). Est-ce que ce raisonnement correct?

(Évidemment sizeof(int) ne peut pas être 1 si CHAR_BIT 8, en raison du minimum requis gamme pour int, nous sommes donc implicitement ne parlons que des implémentations avec CHAR_BIT>=16, par exemple, les Dsp, typique des implémentations serait un autoportant mise en œuvre plutôt que de hébergé mise en œuvre, et donc pas nécessaire de fournir de l' stdio.)

Edit: Après avoir lu les réponses et quelques liens de références, quelques réflexions sur les façons c'est peut-être valable pour une hébergé mise en œuvre de disposer sizeof(int)==1:

Tout d'abord, quelques citations:

7.19.7.1(2-3):

Si la fin de fichier indicateur pour l'entrée de flux pointé par stream n'est pas définie et qu'un le caractère suivant est présent, la fonction fgetc obtient que le caractère non signé char converti en int et avances le fichier associé indicateur de position pour la flux (si défini).

Si la fin de fichier indicateur pour le stream est activé, ou si le flux est en fin de fichier, la fin de fichier indicateur pour le flux est défini et la fonction fgetc retourne EOF. Sinon, l' la fonction fgetc renvoie le caractère suivant à partir de l'entrée de flux pointé par stream. Si une erreur de lecture se produit, l'indicateur d'erreur pour le flux est défini et la fonction fgetc retourne EOF.

7.19.8.1(2):

La fonction fread lit, dans le tableau pointé par ptr, jusqu'à nmemb éléments dont la taille est spécifiée par la taille, à partir du flux pointé par stream. Pour chaque objet, de la taille des appels sont faits à la fonction fgetc et les résultats stockés, dans l'ordre lire, dans un tableau de unsigned char exactement la superposition de l'objet. La position dans le fichier de indicateur pour le stream (si défini) est avancée par le nombre de caractères lus.

Pensées:

  • La lecture arrière unsigned char valeurs en dehors de la plage de int pourrait tout simplement pas défini de mise en œuvre définies par le comportement dans la mise en œuvre. Cela est particulièrement inquiétant, car il signifie que l'utilisation de fwrite et fread pour stocker des structures binaires (qui, même s'il en résulte non portables fichiers, est censé être une opération que vous pouvez effectuer de façon portable sur n'importe quel unique de mise en œuvre) pourrait apparaître à travailler, mais en silence l'échec. essentiellement aboutit toujours à un comportement indéfini. J'accepte qu'une mise en œuvre peut ne pas avoir de système de fichiers utilisable, mais c'est beaucoup plus difficile à accepter qu'une mise en œuvre pourrait avoir un système de fichiers qui appelle automatiquement nasale démons dès que vous essayez de l'utiliser, et aucun moyen de déterminer qu'il est inutilisable. Maintenant que je me rends compte du comportement de la mise en œuvre est définie et non pas défini, il n'est pas si inquiétante, et je pense que cela pourrait être un valide (bien que pas souhaitable) de mise en œuvre.

  • Une mise en oeuvre sizeof(int)==1 pourrait définir simplement le système de fichiers soit vide et en lecture seule. Alors il n'y aurait aucun moyen d'une application peut lire les données écrites par lui-même, uniquement à partir d'un périphérique d'entrée sur stdin qui pourrait être mis en œuvre de façon à ne donner qu'positif char des valeurs qui s'inscrivent dans int.

Edit (encore une fois): à Partir de la C99 Justification, 7.4:

EOF est traditionnellement -1, mais peut-être n'importe quel nombre entier négatif, et donc à distinguer de tout caractère valide code.

Cela semble indiquer qu' sizeof(int) peut ne pas être de 1, ou, au moins, que telle était l'intention du comité.

24voto

Charles Bailey Points 244082

Il est possible pour une mise en œuvre pour répondre aux exigences d'interface pour fgetc et fputc même si sizeof(int) == 1.

L'interface d' fgetc dit qu'il retourne le caractère lu comme un unsigned char converti en int. Nulle part il n'est dit que cette valeur ne peut pas être EOF , même si l'attente est clairement valable lit "habituellement" le retour des valeurs positives. Bien sûr, fgetc retours EOF sur un échec de lecture ou de la fin du flux, mais dans ces cas, le fichier de l'indicateur d'erreur ou de fin de fichier témoin (respectivement) est également définie.

De même, nulle part il n'est dit que vous ne pouvez pas passer EOF de fputc , tant que le coïncide avec la valeur de l' unsigned char converti en int.

Évidemment, le programmeur doit être très prudent sur ces plateformes. C'est ne pourrait pas faire une copie complète:

void Copy(FILE *out, FILE *in)
{
    int c;
    while((c = fgetc(in)) != EOF)
        fputc(c, out);
}

Au lieu de cela, vous auriez à faire quelque chose comme (pas testé!):

void Copy(FILE *out, FILE *in)
{
    int c;
    while((c = fgetc(in)) != EOF || (!feof(in) && !ferror(in)))
        fputc(c, out);
}

Bien sûr, les plates-formes où vous aurez de vrais problèmes sont ceux où l' sizeof(int) == 1 et la conversion de l' unsigned char de int n'est pas une injection. Je crois que ce serait forcément le cas sur les plates-formes à l'aide de signe et l'ampleur ou de complément pour la représentation des entiers signés.

10voto

Secure Points 2838

Je me souviens de cette exacte même question sur comp.lang.c 10 ou 15 ans. À la recherche, j'ai trouvé un plus cours de discussion ici:

http://groups.google.de/group/comp.lang.c/browse_thread/thread/9047fe9cc86e1c6a/cb362cbc90e017ac

Je pense qu'il y a deux faits:

(a) Il peut y avoir des cas d'applications où la conformité n'est pas possible. E. g. sizeof(int)==1 avec un complément ou d'un signe de grandeur des valeurs négatives ou rembourrage de bits dans le type int, c'est à dire pas tous les unsigned char valeurs peuvent être converties en vigueur int valeur.

(b) Le typique idiome ((c=fgetc(in))!=EOF) n'est pas portable (sauf pour CHAR_BIT==8), que les expressions du FOLKLORE n'est pas nécessaire d'être une valeur distincte.

5voto

Jerry Coffin Points 237758

Je ne crois pas que le C standard directement exige que les expressions du FOLKLORE être distincte de toute la valeur de ce qui peut être lu à partir d'un flux. Dans le même temps, il ne semble pas prendre pour acquis qu'il sera. Certaines parties de la norme d'exigences contradictoires que j'ai un doute peut être atteint si EOF est une valeur qui peut être lu à partir d'un flux.

Considérons, par exemple, ungetc. D'une part, la spécification dit (§7.19.7.11):

La fonction ungetc empile le caractère spécifié par c (converti en unsigned char) retour sur l'entrée de flux pointé par stream. Reculée de caractères sera renvoyé par les lectures suivantes sur ce flux dans l'ordre inverse de leur pousse. [ ... ] Un caractère de refoulement est garanti.

Sur l'autre main, il dit aussi:

Si la valeur de c est égale à celle de la macro expressions du FOLKLORE, l'opération échoue et le flux d'entrée est inchangé.

Donc, si EOF est une valeur qui peut être lu à partir du flux, et (par exemple) nous lisons dans le flux et l'utiliser immédiatement ungetc de mettre des expressions du FOLKLORE dans la rivière, nous obtenons une énigme: l'appel est "garanti" pour réussir, mais aussi explicitement requis à l'échec.

À moins que quelqu'un pouvez voir un moyen de concilier ces exigences, je suis à gauche avec beaucoup de doute quant à savoir si une telle mise en œuvre peut se conformer.

Dans le cas où quelqu'un se soucie, N1548 (projet en cours de la nouvelle norme C) conserve les mêmes exigences.

3voto

dmckee Points 50318

Ne serait-il pas suffisant si un nominal char qui avaient en commun une séquence de bits avec EOF a été défini comme non-sens? Si, par exemple, CHAR_BIT était de 16, mais toutes les valeurs autorisées n'occupe que le 15 bits de poids faible (à supposer 2s-complément de signe de magnitude int représentation). Ou tout doit représentable dans un char ont un sens en tant que tel? J'avoue que je ne sais pas.

Bien sûr, ce serait une drôle de bête, mais nous la laissons notre imagination aller ici, non?

R.. m'a convaincu que cela ne va pas ensemble. Parce hébergé mise en œuvre doit mettre en oeuvre stdio.h et si fwrite est d'être en mesure de rester entiers sur le disque, puis fgetc pourrait retourner tout modèle de bits qui auraient leur place dans un char, et qui ne doit pas interférer avec le retour des expressions du FOLKLORE. CQFD.

2voto

Potatoswatter Points 70305

Je ne suis pas familier avec le C99, mais je ne vois pas ce que dit fgetc doit produire une gamme de valeurs de char. Le moyen le plus évident à mettre en œuvre stdio sur un tel système serait de mettre 8 bits dans chaque char, quelle que soit sa capacité. L'exigence d' EOF est

EOF

qui s'étend à un nombre entier expression constante, avec un type int et une valeur négative, qui est retourné par plusieurs fonctions pour indiquer fin-de-fichier, qui n'est pas plus d'entrée à partir d'un flux

La situation est analogue à l' wchar_t et wint_t. Dans 7.24.1/2-3 définissant wint_t et WEOF, note de bas de page 278 dit

wchar_t et wint_t peut être le même type entier.

ce qui semble en être la garantie que les "doux" le contrôle de la portée est suffisante pour garantir que l' *EOF n'est pas dans le jeu de caractères.

Edit:

Ce ne serait pas autoriser les flux binaires, puisque dans un tel cas fputc et fgetc sont nécessaires pour effectuer aucune transformation. (7.19.2/3) les flux Binaires ne sont pas facultatifs; seul leur distinction sur la base de flux de texte est facultatif. Il semblerait donc que ce qui rend une telle mise en œuvre non conforme. Il serait encore parfaitement utilisable, même si, comme longtemps que vous n'essayez pas d'écrire des données binaires à l'extérieur de la 8-bits de large.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X