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

1 2 3 4 5
Avatar
Fabrice
On Sat, 10 Apr 2004 08:24:10 +0000 (UTC), Vincent Lefevre


La portabilité est tout relative. En général, on suppose tout de
même que l'implémentation se comporte de manière "raisonnable".


Bon du coup je suis un peu perdu là (il est grand temps d'aller
dormir!), que dois-je répondre à mon collègue ?

- "Un programme codé en ISO C90 est-il portable ?"


S'il évite les comportements indéfinis et dépendants de
l'implémentation, oui, au sens de la norme. Mais cela ne veut pas dire
qu'il n'y aura pas de problème en pratique, à cause de bugs de
compilo, etc.

Il ne faut pas non plus qu'il écrive quelque chose du genre a//**/b,
car ça ne passe pas en C99. Mais bon, ça m'étonnerait qu'on écrive ce
genre de choses habituellement...



D'accord je pensais que la norme proscrivait l'utilisation des
comportements indéfinis ou d'instructions dont le résultat dépend de
l'implémentation (par exemples celles reposant sur le codage des réels
ou des entiers, les problèmes d'alignement des structures, etc...).
Mais apparemment je dois aussi ajouter cela à mon manuel de codage !

Merci pour la remarque concernant les problèmes de pile, je ne savais
pas qu'on pouvait avoir ce genre de problèmes...

Et merci pour tous ces éclaircissements !



Avatar
Fabrice
On Sat, 10 Apr 2004 08:35:49 +0200, "Jean-Marc"

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 ?

Hello,

nous produisons des programmes en C, qui tournent en production
24h/24h, 7j/7j, dans de grandes banques. Nos programmes, écrit
dans un strict respect de la norme, compilent et s'éxécutent sur NT,
Linux, IBM AIX, SUN solaris, HP, VAX VMS et sur mainframe IBM, sous
OS 390 et sous Z/Os (ici nous sommes en EBCDIC). Nous faisons
énormémen d'entrés sorties (et pas seulement en texte, en binaire
aussi) et le source des programmes est le même pour chaque
client/plateforme.


Ah ! Bel exemple de portabilité !
Puis-je savoir ce que vous avez utilisé comme sous ensemble de la norme
ISO C90 (ou C99) ?
Cf. ma discussion avec Vincent Lefevre, est-ce que par exemple la règle
"le codage devra être fait selon la norme en évitant tout comportement
indéfini ou dépendant de l'implémentation" fut suffisant pour canalyser
les programmeurs ?

Evidemmment, nous avons dans les headers quelques
directives de compilation ou d'inclusion conditionnelle. Par exemple,
pour désigner le retour chariot, tous les modules utilisent la
constante HEXA_CR, et celle ci est définie dans un .h avec la valeur
adéquate en fonction de la plateforme.


Pour les problèmes de retours chariots, nous avons personnellement opté
pour la lecture binaire des fichiers textes. un parseur contenant en
mémoire tous les types de retour chariot de la création a ensuite été
utilisé (en pratique il ne contenait que la recherche de "n" et de
"rn").


Pour les entrés sorties, y compris en binaire, tout va bien tant que
les données
sont écrites et lues sur la même plateforme.

La réponse est donc oui, un programme écrit convenablement, qui ne
fait pas de présuppositions sur tel ou tel comportement dans les cas
non définis par la norme
fonctionne sur n'importe quel OS, en tout cas sur ceux que je viens de
nommer.



Merci c'est plus clair comme ça !
On ne peut donc pas se contenter de coder suivant la norme, il faut
aussi éviter les comportements non défini par la norme (il me semblait
que cette précision était superflue car contenue implicitement dans
"respecter la norme" mais apparement ce n'est pas le cas).

Merci !


Avatar
Fabrice
On 10 Apr 2004 06:46:28 GMT, Emmanuel Delahaye
wrote :

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.


Le problème est que beaucoup de choses ne sont pas définies par la
norme (comportements indéfinis), ce qui peut entrainer un tas de
dysfonctionnements même si on suit la norme à la lettre. Exemple:


D'accord. Comme je l'ai écris aux autres il faut donc que dans mon
manuel de codage je précise "Respectez la norme ET n'utilisez pas de
comportement non défini par la norme"

#include <stdio.h>
int main (void)
{
char *s = "Hello world";

s[4] = 'x';
return 0;
}

Ce code est parfaitement 'légal' (il ne brise aucune regle écrite),
mais il invoque un comportement indéfini (une chaine littérale
pourrait très bien être non modifiable), ce qui est un bug (potentiel
ou avéré).


Ok je comprends la distinction. Malheureusement tout comportement non
défini par la norme ne peut pas toujours être considéré comme un bug
(potentiel ou avéré). Je dois donc ajouter une précision à mon premier
commandement...

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


Si on s'en tient strictement à ce qui est défini, c'est bon.



Sauf apparemment les problèmes de pile dont vous parliez avec Vincent
Lefevre...
Auriez-vous d'autres exemples de non portabilité de programmes qui
auraient dû être portables ?

Merci !


Avatar
Pierre Maurette
Fabrice typa:

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 ?
Il faut dans votre "strictement la norme ISO C90" tenir compte de ce

qui est défini dans la norme comme dépendant de l'implémentation, et
soit s'en abstenir, soit considérer le pire des cas respectant le
comportement garanti. La norme définit donc la portabilité, et par là
même la non portabilité. Et vu comme ça, la non portabilité "assumée"
n'est pas une non conformité:
system("dir *.asm > liste.txt");

Par 'portable partout' j'entends que le programme compilé par n'importe
quel compilateur (respectant la norme) sur n'importe quelle architecture
Limitons nous aux architectures permettant une implémentation conforme

complète (hosted).
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.
En fait, on raisonne à l'envers. Ce sont ces comportements qui

définissent la notion de "strictement conforme" :
Déjà cité par Vincent Lefevre.
<citation issue de C99 et non de C90>
A strictly conforming program shall use only those features of the
language and library specified in this International Standard.²) It
shall not produce output dependent on any unspecified, undefined, or
implementation-defined behavior, and shall not exceed any minimum
implementation limit.

2) A strictly conforming program can use conditional features (such as
those in annex F) provided the
use is guarded by a #ifdef directive with the appropriate macro. For
example:
#ifdef _ _STDC_IEC_559_ _ /* FE_UPWARD defined */
/* ... */
fesetround(FE_UPWARD);
/* ... */
#endif
</citation>
La question est de savoir si ces compilateurs existent, et au moins un
par plateforme (hard + OS) pour que tout ça ait une utilité. En fait,
si toutes les plateformes cibles permettent Gcc (Linux, Windows par
exemple), autant écrire "Gcc portable" même si ce n'est pas "strictly
conforming".
Il me semble (mais je n'en suis pas certain) que des compilateurs
compilant sans erreurs et en fournissant le comportement prévu tout
"strictly conforming program" existent. Il faut, et ce n'est pas
toujours simple, les paramétrer correctement. Ne me demandez pas d'en
citer "au moins un", ce n'est pas une certitude er la vérificatiojn
serait très longue. Je suis satisfait du comportement de Borland C++
5.6 (C++, c'est son nom, je n'y peux rien).
Attention, si l'on rajoute comme critère que, en plus de compiler les
programmes conformes, ces compilateur doivent refuser tout "specific",
ça peut être différent.

Si la norme ne suffit pas, pourriez-vous m'indiquer un sous-ensemble de
la norme pouvant garantir la portabilité ?
Je n'ai pas de liste à proposer, mais il est clair que des fonctions

de la bibliothèque standard comme getenv() ou system() n'en sont pas.
Elles doivent compiler sur toute implémentation se prétendant ISO C90,
mais leur utilisation implique que le comportement ne peut-être
garanti. Sinon, voir la citation de la norme.

Pierre

Avatar
Pierre Maurette
Vincent Lefevre <vincent+ typa:
[...]
Si tu suis strictement la norme, tu ne peux pas faire grand chose,
en particulier aucune entrée-sortie.


Pour les entrées/sorties on peut fonctionner avec des fichiers textes.


Même avec les fichiers texte. La norme dit:

[#5] A strictly conforming program shall use only those
features of the language and library specified in this
International Standard.2) It shall not produce output
dependent on any unspecified, undefined, or implementation-
defined behavior, and shall not exceed any minimum
implementation limit.

Or le codage des caractères dépend de l'implémentation (ce n'est pas
forcément à base d'ASCII, tu as des implémentations en EBCDIC, par
exemple).
Pourriez-vous préciser? Je manque cruellement de machines exotiques

(y'en a pas chez Auchan) pour faire les tests nécessaires à la
compréhension, mais il me semblait que le comportement de:
printf("Helllon");
était défini dans une implémentation hosted. C'est bien "Hello" et
passage à la ligne qui va être "sorti". Ce qui n'est pas garanti,
c'est "l'aspect" de stdout (dont l'existence est néanmoins garantie),
ni surtout que cette instruction y envoie la suite d'octets:
48 65 6C 6C 6F 0D 0A
Pierre



Avatar
Vincent Lefevre
Dans l'article ,
Fabrice écrit:

D'accord je pensais que la norme proscrivait l'utilisation des
comportements indéfinis ou d'instructions dont le résultat dépend de
l'implémentation (par exemples celles reposant sur le codage des réels
ou des entiers, les problèmes d'alignement des structures, etc...).
Mais apparemment je dois aussi ajouter cela à mon manuel de codage !


C'est au programmeur de prendre toutes ses précautions.

Merci pour la remarque concernant les problèmes de pile, je ne savais
pas qu'on pouvait avoir ce genre de problèmes...


Oui, éviter de déclarer de gros tableaux en variable automatique...

--
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
Vincent Lefevre
Dans l'article ,
Pierre Maurette <maurette.pierreATfree.fr@> écrit:

Pourriez-vous préciser? Je manque cruellement de machines exotiques
(y'en a pas chez Auchan) pour faire les tests nécessaires à la
compréhension, mais il me semblait que le comportement de:
printf("Helllon");
était défini dans une implémentation hosted. C'est bien "Hello" et
passage à la ligne qui va être "sorti". Ce qui n'est pas garanti,
c'est "l'aspect" de stdout (dont l'existence est néanmoins garantie),
ni surtout que cette instruction y envoie la suite d'octets:
48 65 6C 6C 6F 0D 0A


Le contenu de stdout en tant qu'octets ou autre peut être tout aussi
important.

--
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
Vincent Lefevre
Dans l'article ,
Fabrice écrit:

Pour les problèmes de retours chariots, nous avons personnellement opté
pour la lecture binaire des fichiers textes. un parseur contenant en
mémoire tous les types de retour chariot de la création a ensuite été
utilisé (en pratique il ne contenait que la recherche de "n" et de
"rn").


Sous Mac OS, les fins de ligne de fichiers texte sont des "r".
Et sous RISC OS, on peut également avoir "nr". Cf

http://www.w3.org/TR/2004/REC-xml11-20040204/#sec-line-ends

pour ce qu'on peut avoir d'autre également, en pratique.

--
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
Emmanuel Delahaye
In 'fr.comp.lang.c', Fabrice wrote:

Auriez-vous d'autres exemples de non portabilité de programmes qui
auraient dû être portables ?


system ("cls");

Signifie "Connect the Launch Sequencer" sur DS9000.

http://dspace.dial.pipex.com/town/green/gfd34/art/

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=cpp
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Avatar
Antoine Leca
En , Fabrice va escriure:
Un collègue m'a posé une question à laquelle je fus incapable de
répondre :


Bizarre.

si on suit strictement la norme ISO C90 est-on garanti
d'avoir un programme portable partout ?


Oui. Si ce n'était pas vrai, il faudrait jeter la norme, puisque c'est
précisement son objet.

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


En général, on se pose la question inverse: quel est le sur-ensemble minimum
de la norme qui ne rompt pas (trop) la portabilité mais qui permet de faire
des choses intéressantes.


Antoine

1 2 3 4 5