OVH Cloud OVH Cloud

Evaluation d'une expression constante

31 réponses
Avatar
candide
Bonjour,

La norme dit :

6.6 Constant expressions
(...)
A constant expression can be evaluated during translation rather than
runtime,


Soit le programme suivant :

/*--------------------------------*/
#include <stdio.h>

#define A 2
#define B 5

int main(void)
{
int i;

for (i = 0; i < A * B; i++)
printf("toto\n");

return 0;
}
/*--------------------------------*/

Ai-je une quelconque garantie que l'expression A*B ne sera pas réévaluée
à chaque tour de boucle pendant l'exécution ?

Merci

10 réponses

1 2 3 4
Avatar
Vincent Lefevre
Dans l'article <gg6svg$rle$,
Antoine Leca écrit:

Moi je dis qu'il est effectivement bien obligé, histoire d'attraper un truc
comme



#include<limits.h>
#define A 2
#define B (INT_MAX+1u)
char a[A*B];



D'autre part, si "char a[A*B];" se trouve dans une fonction (qui
pourrait ne jamais être appelée), doit-on avoir un diagnostic?

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)
Avatar
Antoine Leca
En news:20081121212730$, Vincent Lefevre va
escriure:
Dans l'article <gg6svg$rle$,
Antoine Leca écrit:

En news:20081117175312$, Vincent Lefevre va
escriure:



donc 1 << 16 est aussi positif, et de même que (1 << 16) * 2.
Pas forcément: cf. C99 6.3.1.3p3.







Attends, ceci concerne les *conversions*. Ici, pas de conversion.
Les règles pour les opérations, style * (multiplication), sont
différentes.
Cf 6.5#5: c'est de l'undefined behavior.



Je ne prendrais pas cet argument trop au pied de la lettre: en supposant
#include<limits.h>
#define A 2
#define B (INT_MAX+1u)

6.5p5 revient à dire que le résultat de A*B a un comportement indéfini, car
il est en dehors des valeurs représentables pour le type unsigned int (dans
le cas général) ; même punition pour UINT_MAX+1 ou -1u ; auquel cas il y a
pas mal de code C qui est complètement inutilisable...

Pour que cela marche comme attendu, il faut appliquer 6.3p1 et 6.3.1.8 aux
opérations de la clause 6.5 (après les spécifiques genre 6.5.7p3 mais avant
6.5p5).


Ton propos initial était de refuser l'argument de l'article
<gf9s85$rbc$, où Charlie Gordon
écrit:
- le compilateur est obligé de savoir faire l'évaluation des
expressions constantes au moment de la compilation, sinon
impossible de déclarer ``char a[A * B]''.





Un exemple n'a jamais rien prouvé sur le cas général. Le point
important est qu'il *existe* des expressions constantes que le
compilateur n'a pas besoin d'évaluer complètement (i.e. d'en
connaître le résultat) pour qu'il se comporte de manière conforme
à la norme.



Je ne suis pas d'accord avec ta logique, que je lis comme : il existe au
moins une expression constante pour laquelle un compilateur peut se
permettre de ne pas calculer la valeur au moment de la compilation, donc il
n'est pas obligé de savoir faire l'évaluation des expressions constantes.

Pour moi c'est plutôt : il existe au moins une classe d'expression pour
laquelle le compilateur est (raisonnablement) obligé de calculer une
estimation de la valeur dès la compilation, afin d'émettre les diagnostics
requis par la norme.


De telles expressions constantes peuvent alors très
bien être évaluées à l'exécution.



Encore une fois, personne ne nie cela, au contraire cela a été la première
réponse d'Erwan, de Marc B., ou de moi-même. Et on peut inférer de la
réponse de Wykaaa qu'il est d'acord aussi.


Par exemple, pour A*B sur du non signé, on peut raisonner sur la
valuation 2-adique.



J'ai déjà répondu à cela. On peut toujours inventer des manières de ne pas
calculer le produit, mais cela revient quand même à faire une évaluation de
sa valeur, ici savoir si elle est nulle (c'est même probablement pour cela
que la norme utilise le terme « évaluation » au lieu de « calcul »).


D'autre part, si "char a[A*B];" se trouve dans une fonction (qui
pourrait ne jamais être appelée), doit-on avoir un diagnostic?



Je dirais que oui, cf 5.1.1.3, et la formulation de 6.10.1p5 qui cherche
(peut-être imparfaitement) à autoriser une syntaxe invalide à être présente
dans un groupe sauté par #if 0 ou similaire.


Antoine
Avatar
Vincent Lefevre
Dans l'article <gggk09$7vq$,
Antoine Leca écrit:

6.5p5 revient à dire que le résultat de A*B a un comportement indéfini, car
il est en dehors des valeurs représentables pour le type unsigned int (dans
le cas général) ; même punition pour UINT_MAX+1 ou -1u ;



Pourquoi UINT_MAX+1 est-il du comportement indéfini? Il n'y a pas
d'overflow sur du ***non signé***. Alors je ne comprends pas.

En revanche, je serais d'accord pour INT_MAX+1: comportement indéfini.

auquel cas il y a pas mal de code C qui est complètement
inutilisable...



On a déjà vu ce que donnait du code C mal écrit. De toute façon
là n'est pas la question. Du comportement indéfini reste du
comportement indéfini, même si beaucoup de code C suppose un
comportement particulier. Le compilateur peut toujours compiler
du comportement indéfini de façon à ce qu'on obtienne le
comportement attendu par l'utilisateur (style -fwrapv).

Je ne suis pas d'accord avec ta logique, que je lis comme : il existe au
moins une expression constante pour laquelle un compilateur peut se
permettre de ne pas calculer la valeur au moment de la compilation, donc il
n'est pas obligé de savoir faire l'évaluation des expressions constantes.



Pas de *toutes* les expressions constantes. [Attention à la négation
du "pour tout".]

> De telles expressions constantes peuvent alors très
> bien être évaluées à l'exécution.



Encore une fois, personne ne nie cela, au contraire cela a été la première
réponse d'Erwan, de Marc B., ou de moi-même. Et on peut inférer de la
réponse de Wykaaa qu'il est d'acord aussi.



Pourtant Charlie a dit:

| le compilateur est obligé de savoir faire l'évaluation des expressions
| constantes au moment de la compilation, sinon impossible de déclarer
| ``char a[A * B]''.

Moi je dis:
Avec un compilateur qui ne sait pas faire l'évaluation de toutes les
expressions constantes, il n'est pas forcément impossible de déclarer
``char a[A * B]''.

> Par exemple, pour A*B sur du non signé, on peut raisonner sur la
> valuation 2-adique.



J'ai déjà répondu à cela. On peut toujours inventer des manières de ne pas
calculer le produit, mais cela revient quand même à faire une évaluation de
sa valeur,



Cela revient au même au niveau de la sémantique, mais pas au niveau
du temps de calcul (même si la norme ne se préoccupe pas du temps
de calcul, cette question d'implémentation était dans la question
initiale).

Il y a des raisonnements qui risquent de ne pas tenir si on considère
une implémentation avec des types int sur des milliers de bits (c'est
autorisé par la norme, et ça pourrait être utile en pratique).

> D'autre part, si "char a[A*B];" se trouve dans une fonction (qui
> pourrait ne jamais être appelée), doit-on avoir un diagnostic?



Je dirais que oui, cf 5.1.1.3, et la formulation de 6.10.1p5 qui cherche
(peut-être imparfaitement) à autoriser une syntaxe invalide à être présente
dans un groupe sauté par #if 0 ou similaire.



Alors comment ça se fait que lorsque la contrainte 6.6#4 "Each
constant expression shall evaluate to a constant that is in the
range of representable values for its type." est violée, gcc
n'émet pas toujours un diagnostic? Bug?

Le problème se produit avec une expression constante du style
((1 << 20) * (1 << 20))

Par exemple (sur une machine 32 bits) pour:

int main(void)
{
int x;
x = 0 && ((1 << 20) * (1 << 20));
return 0;
}

En revanche, gcc donne bien le diagnostic pour:

int main(void)
{
int x;
if (0)
x = ((1 << 20) * (1 << 20));
return 0;
}

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)
Avatar
Antoine Leca
En news:20081125164122$, Vincent Lefevre va
escriure:
Dans l'article <gggk09$7vq$,
Antoine Leca écrit:

6.5p5 revient à dire que le résultat de A*B a un comportement
indéfini, car il est en dehors des valeurs représentables pour le
type unsigned int (dans le cas général) ; même punition pour
UINT_MAX+1 ou -1u ;



Pourquoi UINT_MAX+1 est-il du comportement indéfini? Il n'y a pas
d'overflow sur du ***non signé***.



En vertu de quoi ?


Alors je ne comprends pas.



Moi non plus.
Si je lis 6.5p5 (sans considérer 6.3), le résultat brut d'une opération hors
du domaine des valeurs représentables aurait un comportement indéfini.
UINT_MAX+1 est en dehors du domaine des valeurs représentables pour un
unsigned int. -1 non plus ne fait pas partie de ces valeurs.


Je ne suis pas d'accord avec ta logique, que je lis comme : il
existe au moins une expression constante pour laquelle un
compilateur peut se permettre de ne pas calculer la valeur au moment
de la compilation, donc il n'est pas obligé de savoir faire
l'évaluation des expressions constantes.



Pas de *toutes* les expressions constantes. [Attention à la négation
du "pour tout".]



Seul souci, je ne localise pas le « pour tout » dans ce fil non plus
(décidément, ce mois-ci on dirait que j'ai du mal avec les mathématiques).


Pourtant Charlie a dit:
le compilateur est obligé de savoir faire l'évaluation des
expressions constantes au moment de la compilation, sinon impossible
de déclarer ``char a[A * B]''.



Moi je dis:
Avec un compilateur qui ne sait pas faire l'évaluation de toutes les
expressions constantes, il n'est pas forcément impossible de
déclarer ``char a[A * B]''.



Donc vous dites deux choses deux choses distinctes : Chqrlie que le
compilateur _doit_ savoir évaluer [certaines] expressions, et toi qu'il lui
est loisible de ne pas les évaluer _toutes_.

(Le « [certaines] » est dans news:gfhpuk$vvu$)


Cela revient au même au niveau de la sémantique, mais pas au niveau
du temps de calcul (même si la norme ne se préoccupe pas du temps
de calcul, cette question d'implémentation était dans la question
initiale).



Je n'avais pas vu que la question initiale se préoccupe du temps de calcul
*pendant la compilation*.


Alors comment ça se fait que lorsque la contrainte 6.6#4 "Each
constant expression shall evaluate to a constant that is in the
range of representable values for its type." est violée, gcc
n'émet pas toujours un diagnostic? Bug?



http://www.open-std.org/JTC1/SC22/WG14/www/docs/dr_261.htm répond-t-il à ta
question ?

Si non, bogue ou DR.


Antoine
Avatar
Vincent Lefevre
Dans l'article <ggk7bl$j5e$,
Antoine Leca écrit:

En news:20081125164122$, Vincent Lefevre va
escriure:
> Dans l'article <gggk09$7vq$,
> Antoine Leca écrit:
>
>> 6.5p5 revient à dire que le résultat de A*B a un comportement
>> indéfini, car il est en dehors des valeurs représentables pour le
>> type unsigned int (dans le cas général) ; même punition pour
>> UINT_MAX+1 ou -1u ;
>
> Pourquoi UINT_MAX+1 est-il du comportement indéfini? Il n'y a pas
> d'overflow sur du ***non signé***.



En vertu de quoi ?



6.2.5. Je cite: "A computation involving unsigned operands can never
overflow, because a result that cannot be represented by the resulting
unsigned integer type is reduced modulo the number that is one greater
than the largest value that can be represented by the resulting type."

> Alors je ne comprends pas.



Moi non plus.
Si je lis 6.5p5 (sans considérer 6.3), le résultat brut d'une opération hors
du domaine des valeurs représentables aurait un comportement indéfini.



Non, c'est 6.2.5 qui garantit le comportement bien défini (pas besoin de
considérer 6.3, qui ne concerne que les conversions).

>> Je ne suis pas d'accord avec ta logique, que je lis comme : il
>> existe au moins une expression constante pour laquelle un
>> compilateur peut se permettre de ne pas calculer la valeur au moment
>> de la compilation, donc il n'est pas obligé de savoir faire
>> l'évaluation des expressions constantes.
>
> Pas de *toutes* les expressions constantes. [Attention à la négation
> du "pour tout".]



Seul souci, je ne localise pas le « pour tout » dans ce fil non plus
(décidément, ce mois-ci on dirait que j'ai du mal avec les mathématiques).



J'ai supposé que le "pour tout" était implicite, pour que le
raisonnement logique soit correct (i.e. Charlie n'aurait rien
pu déduire sur l'expression *particulière* donnée dans l'exemple).

> Pourtant Charlie a dit:
>> le compilateur est obligé de savoir faire l'évaluation des
>> expressions constantes au moment de la compilation, sinon impossible
>> de déclarer ``char a[A * B]''.
>
> Moi je dis:
> Avec un compilateur qui ne sait pas faire l'évaluation de toutes les
> expressions constantes, il n'est pas forcément impossible de
> déclarer ``char a[A * B]''.



Donc vous dites deux choses deux choses distinctes : Chqrlie que le
compilateur _doit_ savoir évaluer [certaines] expressions, et toi qu'il lui
est loisible de ne pas les évaluer _toutes_.



Cf ci-dessus.

> Alors comment ça se fait que lorsque la contrainte 6.6#4 "Each
> constant expression shall evaluate to a constant that is in the
> range of representable values for its type." est violée, gcc
> n'émet pas toujours un diagnostic? Bug?



http://www.open-std.org/JTC1/SC22/WG14/www/docs/dr_261.htm répond-t-il à ta
question ?



Il va falloir que je regarde de près, mais je n'ai pas l'impression que
ça répond à ma question sans poser des problèmes avec d'autres parties
de la norme.

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)
Avatar
Charlie Gordon
"Antoine Leca" a écrit dans le message de news:
ggk7bl$j5e$
En news:20081125164122$, Vincent Lefevre va
escriure:
Dans l'article <gggk09$7vq$,
Antoine Leca écrit:

6.5p5 revient à dire que le résultat de A*B a un comportement
indéfini, car il est en dehors des valeurs représentables pour le
type unsigned int (dans le cas général) ; même punition pour
UINT_MAX+1 ou -1u ;



Pourquoi UINT_MAX+1 est-il du comportement indéfini? Il n'y a pas
d'overflow sur du ***non signé***.



En vertu de quoi ?



L'arithmetique sur les entiers non signés est définie par la norme : le
calcul se fait modulo 2 puissance n ou n est le nombre de bits significatifs
de valeur. On en déduit que UINT_MAX+1 vaut 0.

Alors je ne comprends pas.



Moi non plus.
Si je lis 6.5p5 (sans considérer 6.3), le résultat brut d'une opération
hors
du domaine des valeurs représentables aurait un comportement indéfini.
UINT_MAX+1 est en dehors du domaine des valeurs représentables pour un
unsigned int. -1 non plus ne fait pas partie de ces valeurs.



-1U vaut exactement UINT_MAX, pour la même raison que ci-dessus.

Pour les experts, notons tout de même que le préprocesseur évalue les
expressions de contrôle des blocs conditionnels #if et #elif comme si tous
les types entiers signés (resp. non signés) étaient identiques à intmax_t
(resp. uintmax_t). Donc l'expression de contrôle UINT_MAX+1 est non nulle
sauf dans le cas très particulier où UINT_MAX == UINTMAX_MAX, c'est à dire
que int et intmax_t ont la même représentation, ce qui implique que long et
long long aient aussi cette représentation et donc fasse au moins 64 bits,
dans ce cas seulement, #if UINT_MAX+1 s'évalue comme #if 0

...
Pourtant Charlie a dit:
le compilateur est obligé de savoir faire l'évaluation des
expressions constantes au moment de la compilation, sinon impossible
de déclarer ``char a[A * B]''.



Moi je dis:
Avec un compilateur qui ne sait pas faire l'évaluation de toutes les
expressions constantes, il n'est pas forcément impossible de
déclarer ``char a[A * B]''.



Donc vous dites deux choses deux choses distinctes : Chqrlie que le
compilateur _doit_ savoir évaluer [certaines] expressions, et toi qu'il
lui
est loisible de ne pas les évaluer _toutes_.



En fait la deuxième affirmation est mal formulée : "un compilateur qui ne
sait pas faire l'évaluation de toutes les expressions contantes" ne me
semble pas conforme à la norme, en revanche rien n'oblige un compilateur
conforme à faire l'évaluation des expressions constantes à la compilation
dans les cas où cela n'est pas nécessaire pour compiler du code conforme,
mais que gagnerait le compilateur à ne pas faire cette optimisation simple ?
Même tcc fait le constant folding.

--
Chqrlie.
Avatar
Vincent Lefevre
Dans l'article <ggpeii$6ld$,
Charlie Gordon écrit:

"Antoine Leca" a écrit dans le message de news:
ggk7bl$j5e$
> En news:20081125164122$, Vincent Lefevre va
> escriure:
>> Dans l'article <gggk09$7vq$,
>> Antoine Leca écrit:



...
>> Pourtant Charlie a dit:
>>> le compilateur est obligé de savoir faire l'évaluation des
>>> expressions constantes au moment de la compilation, sinon impossible
>>> de déclarer ``char a[A * B]''.
>>
>> Moi je dis:
>> Avec un compilateur qui ne sait pas faire l'évaluation de toutes les
>> expressions constantes, il n'est pas forcément impossible de
>> déclarer ``char a[A * B]''.
>
> Donc vous dites deux choses deux choses distinctes : Chqrlie que
> le compilateur _doit_ savoir évaluer [certaines] expressions, et
> toi qu'il lui est loisible de ne pas les évaluer _toutes_.



En fait la deuxième affirmation est mal formulée : "un compilateur qui ne
sait pas faire l'évaluation de toutes les expressions contantes" ne me
semble pas conforme à la norme,



Je ne suis pas d'accord. De toute façon, je me rend compte maintenant
que c'est stupide: dans la pratique, aucun compilateur ne sait évaluer
toutes les expressions constantes, car on peut toujours lui fournir
quelque chose de tellement compliqué qu'on va faire exploser les
limites de la machine. :) (Et aucune implémentation n'est évidemment
requise de traduire tout programme conforme.)

Mais cela conforte ce que j'ai dit (les limites de la machine étant
une notion floue): on peut très bien supposer que le compilateur ne
sait évaluer aucune expression constante (autre que les constantes),
le cas A * B pouvant se résoudre par un calcul de valuation 2-adique.
Un tel compilateur va râler sur de nombreux programmes conformes, mais
certainement pas à cause de ``char a[A * B]''.

en revanche rien n'oblige un compilateur conforme à faire
l'évaluation des expressions constantes à la compilation dans les
cas où cela n'est pas nécessaire pour compiler du code conforme,
mais que gagnerait le compilateur à ne pas faire cette optimisation
simple ?



On peut faire des justifications très tordues sur des implémentations
possibles, mais qui n'existent pas en pratique.

Mais déjà, l'évaluation de constantes flottantes (i.e. la conversion
base 10 -> base 2) est un problème assez compliqué[*], et si le
compilateur sait que certaines constantes ne seront probablement pas
évaluées, il peut laisser l'évaluation éventuelle à l'exécution afin
d'avoir un temps de compilation plus court.

[*] au point que certaines implémentations sont buggées, cf par exemple:

http://sourceware.org/bugzilla/show_bug.cgi?id479

et (mentionné dans ce bug de la glibc):

http://gcc.gnu.org/bugzilla/show_bug.cgi?id!718

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)
Avatar
Vincent Lefevre
Dans l'article <ggpeii$6ld$,
Charlie Gordon écrit:

"Antoine Leca" a écrit dans le message de news:
ggk7bl$j5e$
> En news:20081125164122$, Vincent Lefevre va
> escriure:
>> Dans l'article <gggk09$7vq$,
>> Antoine Leca écrit:



...
>> Pourtant Charlie a dit:
>>> le compilateur est obligé de savoir faire l'évaluation des
>>> expressions constantes au moment de la compilation, sinon impossible
>>> de déclarer ``char a[A * B]''.
>>
>> Moi je dis:
>> Avec un compilateur qui ne sait pas faire l'évaluation de toutes les
>> expressions constantes, il n'est pas forcément impossible de
>> déclarer ``char a[A * B]''.
>
> Donc vous dites deux choses deux choses distinctes : Chqrlie que
> le compilateur _doit_ savoir évaluer [certaines] expressions, et
> toi qu'il lui est loisible de ne pas les évaluer _toutes_.



En fait la deuxième affirmation est mal formulée : "un compilateur qui ne
sait pas faire l'évaluation de toutes les expressions contantes" ne me
semble pas conforme à la norme,



Je ne suis pas d'accord. De toute façon, je me rends compte maintenant
que c'est stupide: dans la pratique, aucun compilateur ne sait évaluer
toutes les expressions constantes, car on peut toujours lui fournir
quelque chose de tellement compliqué qu'on va faire exploser les
limites de la machine. :) (Et aucune implémentation n'est évidemment
requise de traduire tout programme conforme.)

Mais cela conforte ce que j'ai dit (les limites de la machine étant
une notion floue): on peut très bien supposer que le compilateur ne
sait évaluer aucune expression constante (autre que les constantes),
le cas A * B pouvant se résoudre par un calcul de valuation 2-adique.
Un tel compilateur va râler sur de nombreux programmes conformes, mais
certainement pas à cause de ``char a[A * B]''.

en revanche rien n'oblige un compilateur conforme à faire
l'évaluation des expressions constantes à la compilation dans les
cas où cela n'est pas nécessaire pour compiler du code conforme,
mais que gagnerait le compilateur à ne pas faire cette optimisation
simple ?



On peut faire des justifications très tordues sur des implémentations
possibles, mais qui n'existent pas en pratique.

Mais déjà, l'évaluation de constantes flottantes (i.e. la conversion
base 10 -> base 2) est un problème assez compliqué[*], et si le
compilateur sait que certaines constantes ne seront probablement pas
évaluées, il peut laisser l'évaluation éventuelle à l'exécution afin
d'avoir un temps de compilation plus court.

[*] au point que certaines implémentations sont buggées, cf par exemple:

http://sourceware.org/bugzilla/show_bug.cgi?id479

et (mentionné dans ce bug de la glibc):

http://gcc.gnu.org/bugzilla/show_bug.cgi?id!718

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)
Avatar
Vincent Lefevre
Dans l'article <ggk7bl$j5e$,
Antoine Leca écrit:

> Alors comment ça se fait que lorsque la contrainte 6.6#4 "Each
> constant expression shall evaluate to a constant that is in the
> range of representable values for its type." est violée, gcc
> n'émet pas toujours un diagnostic? Bug?



http://www.open-std.org/JTC1/SC22/WG14/www/docs/dr_261.htm répond-t-il à ta
question ?



D'accord, si je comprends bien, il y a une interprétation valide
en considérant que ((1 << 20) * (1 << 20)) n'est pas une expression
constante, donc on ne considère pas que c'est une expression
constante qui viole une contrainte.

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)
Avatar
espie
In article <20081128234414$,
Vincent Lefevre <vincent+ wrote:
Dans l'article <ggpeii$6ld$,
Charlie Gordon écrit:

"Antoine Leca" a écrit dans le message de news:
ggk7bl$j5e$
> En news:20081125164122$, Vincent Lefevre va
> escriure:
>> Dans l'article <gggk09$7vq$,
>> Antoine Leca écrit:



...
>> Pourtant Charlie a dit:
>>> le compilateur est obligé de savoir faire l'évaluation des
>>> expressions constantes au moment de la compilation, sinon impossible
>>> de déclarer ``char a[A * B]''.
>>
>> Moi je dis:
>> Avec un compilateur qui ne sait pas faire l'évaluation de toutes les
>> expressions constantes, il n'est pas forcément impossible de
>> déclarer ``char a[A * B]''.
>
> Donc vous dites deux choses deux choses distinctes : Chqrlie que
> le compilateur _doit_ savoir évaluer [certaines] expressions, et
> toi qu'il lui est loisible de ne pas les évaluer _toutes_.



En fait la deuxième affirmation est mal formulée : "un compilateur qui ne
sait pas faire l'évaluation de toutes les expressions contantes" ne me
semble pas conforme à la norme,



Je ne suis pas d'accord. De toute façon, je me rends compte maintenant
que c'est stupide: dans la pratique, aucun compilateur ne sait évaluer
toutes les expressions constantes, car on peut toujours lui fournir
quelque chose de tellement compliqué qu'on va faire exploser les
limites de la machine. :) (Et aucune implémentation n'est évidemment
requise de traduire tout programme conforme.)



Il me semble justement qu'il y a un bout de paragraphe tout au debut de
la norme qui fixe ces limites (longueur maximale d'expression, niveau
de parentheses etc). J'aurais un peu tendance a penser que tu pipotes.

A cote de ca, il n'existe certainement aucune implementation completement
conforme. On est dans le vrai monde, et elles ont toutes des bugs.
1 2 3 4