Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Y a-t-il des lacunes dans la norme ISO C90 ?

61 réponses
Avatar
Fabrice
Bonjour,

Un collègue m'a posé une question à laquelle je fus incapable de
répondre : si on suit strictement la norme ISO C90 est-on garanti
d'avoir un programme portable partout ?

Par 'portable partout' j'entends que le programme compilé par n'importe
quel compilateur (respectant la norme) sur n'importe quelle architecture
donne le même résultat (aux erreurs de précision numérique et aux bugs
du compilateur près).

La véritable question est en fait de savoir si la norme est suffisante
ou bien s'il y a des lacunes dedans pour garantir qu'un programme sera
portable.

Si la norme ne suffit pas, pourriez-vous m'indiquer un sous-ensemble de
la norme pouvant garantir la portabilité ?

Merci d'avance !

10 réponses

Avatar
Antoine Leca
En , Laurent Wacrenier va escriure:
Antoine Leca écrit:
C'est sensé renvoyer un 'a' dans le jeu de caractères des char du
compilateur,


Pas du compilateur, celui de l'hôte.
Celui du compilateur n'a rien à voir (sauf dans les expressions #if)


Essayez de compiler le code avec un compilateur completement ASCII et
d'executer le programme résultant sur un terminal EBCDIC branché sur
le même hôte.

Vous devriez obtenir de la bouillie.


Jamais réussi à faire marcher un terminal EBCDIC sur une machine ASCII, sauf
à utiliser un protocole genre telnet3270, et dans ce cas-là, il « suffit »
de paramétrer le terminal en ASCII pour que cela fonctionne; mais ce n'est
pas le propos.


Par contre, si le compilateur, tout en prenant le code en ASCII,
transcode les char constants en EBCDIC, le résultat sera présentable.


Oui (c'est exactement ce que fait telnet3270 à l'émission), mais on ne parle
pas de cela.

J'ai des compilateurs (croisés) qui tourne sur des machines ASCII. Le source
peut être en ASCII ou en EBCDIC ou en Unicode, peut importe, il sera traduit
en ASCII (seule chose que comprend le compilateur: c'est le jeu de
caractères du compilateur) à l'entrée. Le compilateur, lui génère du code
pour la machine IBM. Dans le binaire produit, les chaînes sont encodées en
EBCDIC, jeu de caractères de l'hôte. Ensuite, le binaire est exécuté sur
l'IBM, qui sort le code binaire de 'a' (0201), qui est envoyé [on sort du
cadre du C, ici] vers l'équipement récepteur, par exemple un terminal (qui,
s'il fonctionne en ASCII ou en Unicode comme c'est souvent mon cas, va
refaire la traduction dans l'autre sens ;-)).

Si mon compilateur ne faisait pas cette traduction ASCII vers EBCDIC, le
résultat serait inutilisable; bouillie, comme vous dîtes.



Ce que le lecteur verra sur la sortie standard ne sera pas
nessessairement un 'a'.


Si c'est bien configuré (prémisse indispensable, comme toujours en
informatique), si.

5.2.2 Character display semantics

1 [...] The intent of writing a printing character (as defined by the
isprint function) to a display device is to display a graphic representation
of that character at the active position [...]


Ce ne sera pas nessessairement un caractère
non plus (une séquence d'échapement, un bout de caractère, un groupe
de caractères, etc.)


Je ne vois vraiment pas d'où vous justifiez cela. Pas vu de bout ou de
groupe de caractères dans la norme. Et les séquences d'échappement sont
définis par d'autres codes, différents.


Maintenant, bien sûr, si on accouple un terminal EBCDIC à un robot-mixer
complètement ASCII, on va obtenir de la bouillie. Mais avouez que c'est pas
pour cela qu'est fait le terminal EBCDIC...


Antoine



Avatar
Vincent Lefevre
Dans l'article <c5h0r8$ani$,
Antoine Leca écrit:

En , Laurent Wacrenier va escriure:
Vincent Lefevre <vincent+ écrit:
Donc la sortie de putchar('a'); dépend de l'implémentation, car le
code de 'a' n'est pas le même avec toutes les implémentations.


C'est sensé renvoyer un 'a' dans le jeu de caractères des char du
compilateur,


Pas du compilateur, celui de l'hôte.


C'est plus lié au compilateur (en fait à l'ensemble de l'environnement).
En effet, le jeu de caractères dépend de la localisation, en supposant
que le jeu de caractères courant est supporté par le compilateur.

si tant est que la sortie standart existe. Ça renvoie
donc toujours la même chose, même si la sémantique peut changer selon
la sortie standard.


La sémantique sera la même, non ?


Tout dépend de ce qu'on entend par sémantique.

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% validated (X)HTML - Acorn / RISC OS / ARM, free software, YP17,
Championnat International des Jeux Mathématiques et Logiques, etc.
Work: CR INRIA - computer arithmetic / SPACES project at LORIA



Avatar
Antoine Leca
En 20040413163318$, Vincent Lefevre va escriure:
C'est sensé renvoyer un 'a' dans le jeu de caractères des char du
compilateur,


Pas du compilateur, celui de l'hôte.


C'est plus lié au compilateur (en fait à l'ensemble de
l'environnement).


?

Le jeu de caractère de l'environnement, c'est celui de l'hôte.
Celui du compilateur n'a pas grand chose à voir avec tout cela.

Imagine donc un compilateur *nix qui fonctionne avec comme jeu de caractère
interne, Unicode (parfaitement vraissemblable aujourd'hui, non).
L'environnement, *nix donc, de son côté, possède un jeu de caractères
compatible selon toute probabilité ASCII. Qui, selon la locale en cours et
l'appel ou pas à setlocale(), sera peut-être UTF-8 ou "POSIX", mais peut
être aussi iso-8859-? ou n'importe quoi d'autre. Et c'est ce dernier qui
importe pour dire ce que représente (char)65. Pas la valeur (int)65 utilisée
par le compilateur.


En effet, le jeu de caractères dépend de la
localisation, en supposant que le jeu de caractères courant est
supporté par le compilateur.


En général, les compilateurs savent peu de choses sur les jeux de caractères
de l'environnement. Et en fait, s'il n'y avait pas les sympathiques (?)
mb*wc et compagnie, avec la nécessité de traduire les L"..." et autres UCNs,
je pense qu'ils pourraient en ignorer tout en dehors du jeu de base.

Sachant que les mb*wc ont été rajoutés assez tardivement dans la norme ANSI,
je pense que le dessin initial était que le compilateur n'ait rien à savoir
du jeu de caractères étendu. Mais cela n'a pas résisté à la fièvre
normalisatrice...


Antoine



Avatar
Laurent Wacrenier
Antoine Leca écrit:
Je ne vois vraiment pas d'où vous justifiez cela. Pas vu de bout ou de
groupe de caractères dans la norme. Et les séquences d'échappement sont
définis par d'autres codes, différents.


Rien ne dit qu'un char sur une implémentation sera un caractère unique
et bien formé sur tous les périphériques d'affichage

Avatar
Antoine Leca
En , Laurent Wacrenier va escriure:
Rien ne dit qu'un char sur une implémentation sera un caractère unique
et bien formé sur tous les périphériques d'affichage


Non. Et c'est bien pour cela que j'ai initialement restreint aux caractères
imprimables (ce qu'est, normalement, 'a'). Et on peut rajouter que la norme
s'est protégée en affirmant que c'est « l'intention », ce n'est pas toujours
vrai (on a pas de certitude dans ce domaine, par exemple parce qu'il y a
toujours quelqu'un pour essayer de faire marcher le distributeur de gobelets
de café en y branchant un terminal EBCDIC, ce qui va sûrement refaire un peu
plus de bouillie... ;-))


Antoine

Avatar
Vincent Lefevre
Dans l'article <c5h988$hcv$,
Antoine Leca écrit:

En 20040413163318$, Vincent Lefevre va escriure:
C'est sensé renvoyer un 'a' dans le jeu de caractères des char du
compilateur,


Pas du compilateur, celui de l'hôte.


C'est plus lié au compilateur (en fait à l'ensemble de
l'environnement).


?

Le jeu de caractère de l'environnement, c'est celui de l'hôte.


Le jeu de caractères n'est pas lié à l'hôte, mais au processus
(comme l'ensemble des locales). Dans le cas d'une compilation,
le processus est le compilateur (enfin, il peut y avoir plusieurs
processus, mais je suppose qu'il n'y aura pas de changement de
jeu de caractères à ce niveau).

Celui du compilateur n'a pas grand chose à voir avec tout cela.

Imagine donc un compilateur *nix qui fonctionne avec comme jeu de
caractère interne, Unicode (parfaitement vraissemblable aujourd'hui,
non).


C'est invraissemblable avec des char sur 8 bits (cas de la majorité
des *nix -- enfin je ne connais aucun *nix où ça ne peut être
autrement). Sinon, que signifie

putchar('é');

avec Unicode comme jeu de caractères?

L'environnement, *nix donc, de son côté, possède un jeu de
caractères compatible selon toute probabilité ASCII. Qui, selon la
locale en cours et l'appel ou pas à setlocale(), sera peut-être
UTF-8 ou "POSIX", mais peut être aussi iso-8859-? ou n'importe quoi
d'autre. Et c'est ce dernier qui importe pour dire ce que représente
(char)65. Pas la valeur (int)65 utilisée par le compilateur.


Je parlais de la locale utilisée pour la compilation et non pas
pour le lancement du programme (bien qu'en pratique, il me semble
qu'il vaille mieux que ce soient des locales compatibles si des
caractères non ASCII sont en dur dans le source).

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% validated (X)HTML - Acorn / RISC OS / ARM, free software, YP17,
Championnat International des Jeux Mathématiques et Logiques, etc.
Work: CR INRIA - computer arithmetic / SPACES project at LORIA




Avatar
Éric Lévénez
Le 13/04/04 20:33, dans <20040413182354$, « Vincent
Lefevre » <vincent+ a écrit :

Dans l'article <c5h988$hcv$,
Antoine Leca écrit:

Imagine donc un compilateur *nix qui fonctionne avec comme jeu de
caractère interne, Unicode (parfaitement vraissemblable aujourd'hui,
non).


C'est invraissemblable avec des char sur 8 bits (cas de la majorité
des *nix -- enfin je ne connais aucun *nix où ça ne peut être
autrement).


Tout dépend de ce que l'on appelle "interne" d'unix. Par exemple sur Mac OS
X, qui est un unix, l'interface des fichiers doit utiliser des caractères en
UTF-8 (Unicode 4 sous Panther). L'utilisation d'un nom de fichier avec une
séquence de char 8 bits non conforme UTF-8 retourne une erreur,
contrairement aux autres unix. L'interface d'affichage dépend, elle, de
l'émulation choisie dans Terminal, qui est par défaut UTF-8.

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.


Avatar
Laurent Wacrenier
Éric Lévénez écrit:
Tout dépend de ce que l'on appelle "interne" d'unix. Par exemple sur Mac OS
X, qui est un unix, l'interface des fichiers doit utiliser des caractères en
UTF-8 (Unicode 4 sous Panther). L'utilisation d'un nom de fichier avec une
séquence de char 8 bits non conforme UTF-8 retourne une erreur,
contrairement aux autres unix.


Je ne connais pas MacOS, mais ça semble être une fonctionalité du
système de fichiers. Sur un autre système de fichier du même OS (par
exemple, un ISO9960 pour les CD), le jeu de caractère peut être
différent.

L'interface d'affichage dépend, elle, de
l'émulation choisie dans Terminal, qui est par défaut UTF-8.


Avatar
Laurent Wacrenier
Antoine Leca écrit:
En , Laurent Wacrenier va escriure:
Rien ne dit qu'un char sur une implémentation sera un caractère unique
et bien formé sur tous les périphériques d'affichage


Non. Et c'est bien pour cela que j'ai initialement restreint aux caractères
imprimables (ce qu'est, normalement, 'a').


La représenation sur un système du char imprimable 'a' sur un
autre système n'est pas nessessairement un caractère imprimable, ni
même un caractère.


Avatar
Fabrice
On Sat, 10 Apr 2004 11:49:34 +0200, Pierre Maurette

[snip la réponse exhaustive]

Merci beaucoup pour cette réponse très complète !