Dans l'article <491cb231$0$8219$, Mickaël Wolff écrit:
Vincent Lefevre a écrit :
On peut très bien détecter le signe du résultat sans effectuer le produit!
En mathématique peut-être, mais en informatique pas forcément. Surtout pas avec les nombres signés. Sans le calculer, c'est difficile de savoir si (1 << 16) * 2 est positif ou négatif.
1 est un entier signé positif, donc 1 << 16 est aussi positif, et de même que (1 << 16) * 2. Rappel: il n'y a pas de wrapping sur les entiers signés.
Est-ce que c'est vrai pour toutes les valeurs de 16 ?
void foo() { int tab[ ( 1 << 30 ) * 2 ] ; }
$ gcc -c foo.c foo.c: In function 'foo': foo.c:3: warning: integer overflow in expression foo.c:3: error: size of array 'tab' is negative
Vincent Lefevre a écrit :
Dans l'article <491cb231$0$8219$426a74cc@news.free.fr>,
Mickaël Wolff <mickael.wolff@laposte.net> écrit:
Vincent Lefevre a écrit :
On peut très bien détecter le signe du résultat sans effectuer le
produit!
En mathématique peut-être, mais en informatique pas forcément.
Surtout pas avec les nombres signés. Sans le calculer, c'est difficile
de savoir si (1 << 16) * 2 est positif ou négatif.
1 est un entier signé positif, donc 1 << 16 est aussi positif, et
de même que (1 << 16) * 2. Rappel: il n'y a pas de wrapping sur
les entiers signés.
Est-ce que c'est vrai pour toutes les valeurs de 16 ?
void foo()
{
int tab[ ( 1 << 30 ) * 2 ] ;
}
$ gcc -c foo.c
foo.c: In function 'foo':
foo.c:3: warning: integer overflow in expression
foo.c:3: error: size of array 'tab' is negative
Dans l'article <491cb231$0$8219$, Mickaël Wolff écrit:
Vincent Lefevre a écrit :
On peut très bien détecter le signe du résultat sans effectuer le produit!
En mathématique peut-être, mais en informatique pas forcément. Surtout pas avec les nombres signés. Sans le calculer, c'est difficile de savoir si (1 << 16) * 2 est positif ou négatif.
1 est un entier signé positif, donc 1 << 16 est aussi positif, et de même que (1 << 16) * 2. Rappel: il n'y a pas de wrapping sur les entiers signés.
Est-ce que c'est vrai pour toutes les valeurs de 16 ?
void foo() { int tab[ ( 1 << 30 ) * 2 ] ; }
$ gcc -c foo.c foo.c: In function 'foo': foo.c:3: warning: integer overflow in expression foo.c:3: error: size of array 'tab' is negative
Vincent Lefevre
Dans l'article <gfjqfj$g69$, Michel Decima écrit:
Est-ce que c'est vrai pour toutes les valeurs de 16 ?
Oui, toutes celles où l'expression est bien définie (pas d'overflow).
void foo() { int tab[ ( 1 << 30 ) * 2 ] ; }
$ gcc -c foo.c foo.c: In function 'foo': foo.c:3: warning: integer overflow in expression
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
foo.c:3: error: size of array 'tab' is negative
Cette erreur, c'est spécifique à l'implémentation, conséquence de l'integer overflow. L'implémentation aurait très bien pu choisir de donner une valeur positive à ( 1 << 30 ) * 2, auquel cas le programme aurait pu être compilé (éventuellement sans warning).
Dans l'article <gfjqfj$g69$1@news.rd.francetelecom.fr>,
Michel Decima <michel.decima@orange-ft.com> écrit:
Est-ce que c'est vrai pour toutes les valeurs de 16 ?
Oui, toutes celles où l'expression est bien définie (pas d'overflow).
void foo()
{
int tab[ ( 1 << 30 ) * 2 ] ;
}
$ gcc -c foo.c
foo.c: In function 'foo':
foo.c:3: warning: integer overflow in expression
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
foo.c:3: error: size of array 'tab' is negative
Cette erreur, c'est spécifique à l'implémentation, conséquence
de l'integer overflow. L'implémentation aurait très bien pu
choisir de donner une valeur positive à ( 1 << 30 ) * 2, auquel
cas le programme aurait pu être compilé (éventuellement sans
warning).
Est-ce que c'est vrai pour toutes les valeurs de 16 ?
Oui, toutes celles où l'expression est bien définie (pas d'overflow).
void foo() { int tab[ ( 1 << 30 ) * 2 ] ; }
$ gcc -c foo.c foo.c: In function 'foo': foo.c:3: warning: integer overflow in expression
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
foo.c:3: error: size of array 'tab' is negative
Cette erreur, c'est spécifique à l'implémentation, conséquence de l'integer overflow. L'implémentation aurait très bien pu choisir de donner une valeur positive à ( 1 << 30 ) * 2, auquel cas le programme aurait pu être compilé (éventuellement sans warning).
Est-ce que c'est vrai pour toutes les valeurs de 16 ?
Oui, toutes celles où l'expression est bien définie (pas d'overflow).
C'est bien ce que je voulais entendre, et cette notion d'overflow n'apparaissait pas dans ta justification de (1<<16)*2 est positif.
Je reformule la remarque de Mickael en remplacant le verbe "calculer":
"Sans verifier que l'expression est bien definie sur la plateforme cible (pas d'overflow), il est difficile de savoir si (1<<16)*2 est positif ou negatif."
void foo() { int tab[ ( 1 << 30 ) * 2 ] ; }
$ gcc -c foo.c foo.c: In function 'foo': foo.c:3: warning: integer overflow in expression
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
foo.c:3: error: size of array 'tab' is negative
Cette erreur, c'est spécifique à l'implémentation, conséquence de l'integer overflow. L'implémentation aurait très bien pu choisir de donner une valeur positive à ( 1 << 30 ) * 2, auquel cas le programme aurait pu être compilé (éventuellement sans warning).
Oui. Connaissant l'implementation, j'ai choisi expres une grande valeur de 16 pour provoquer l'apparition d'une valeur negative.
Je comprends bien que ce comportement est specifique a l'implementation, mais j'observe la meme chose sur toutes les plateformes auquel j'ai acces (linux/x86, hpux/ia64, aix/power). Evidemment, ca ne prouve rien pour les autres ;)
Vincent Lefevre a écrit :
Dans l'article <gfjqfj$g69$1@news.rd.francetelecom.fr>,
Michel Decima <michel.decima@orange-ft.com> écrit:
Est-ce que c'est vrai pour toutes les valeurs de 16 ?
Oui, toutes celles où l'expression est bien définie (pas d'overflow).
C'est bien ce que je voulais entendre, et cette notion d'overflow
n'apparaissait pas dans ta justification de (1<<16)*2 est positif.
Je reformule la remarque de Mickael en remplacant le verbe "calculer":
"Sans verifier que l'expression est bien definie sur la plateforme cible
(pas d'overflow), il est difficile de savoir si (1<<16)*2 est positif
ou negatif."
void foo()
{
int tab[ ( 1 << 30 ) * 2 ] ;
}
$ gcc -c foo.c
foo.c: In function 'foo':
foo.c:3: warning: integer overflow in expression
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
foo.c:3: error: size of array 'tab' is negative
Cette erreur, c'est spécifique à l'implémentation, conséquence
de l'integer overflow. L'implémentation aurait très bien pu
choisir de donner une valeur positive à ( 1 << 30 ) * 2, auquel
cas le programme aurait pu être compilé (éventuellement sans
warning).
Oui. Connaissant l'implementation, j'ai choisi expres une grande valeur
de 16 pour provoquer l'apparition d'une valeur negative.
Je comprends bien que ce comportement est specifique a l'implementation,
mais j'observe la meme chose sur toutes les plateformes auquel j'ai
acces (linux/x86, hpux/ia64, aix/power). Evidemment, ca ne prouve rien
pour les autres ;)
Est-ce que c'est vrai pour toutes les valeurs de 16 ?
Oui, toutes celles où l'expression est bien définie (pas d'overflow).
C'est bien ce que je voulais entendre, et cette notion d'overflow n'apparaissait pas dans ta justification de (1<<16)*2 est positif.
Je reformule la remarque de Mickael en remplacant le verbe "calculer":
"Sans verifier que l'expression est bien definie sur la plateforme cible (pas d'overflow), il est difficile de savoir si (1<<16)*2 est positif ou negatif."
void foo() { int tab[ ( 1 << 30 ) * 2 ] ; }
$ gcc -c foo.c foo.c: In function 'foo': foo.c:3: warning: integer overflow in expression
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
foo.c:3: error: size of array 'tab' is negative
Cette erreur, c'est spécifique à l'implémentation, conséquence de l'integer overflow. L'implémentation aurait très bien pu choisir de donner une valeur positive à ( 1 << 30 ) * 2, auquel cas le programme aurait pu être compilé (éventuellement sans warning).
Oui. Connaissant l'implementation, j'ai choisi expres une grande valeur de 16 pour provoquer l'apparition d'une valeur negative.
Je comprends bien que ce comportement est specifique a l'implementation, mais j'observe la meme chose sur toutes les plateformes auquel j'ai acces (linux/x86, hpux/ia64, aix/power). Evidemment, ca ne prouve rien pour les autres ;)
Antoine Leca
En news:20081117012443$, Vincent Lefevre va escriure:
Dans l'article <gfjqfj$g69$, Michel Decima écrit:
Est-ce que c'est vrai pour toutes les valeurs de 16 ?
Oui, toutes celles où l'expression est bien définie (pas d'overflow).
<zap>
foo.c:3: warning: integer overflow in expression
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
foo.c:3: error: size of array 'tab' is negative
Cette erreur, c'est spécifique à l'implémentation, conséquence de l'integer overflow.
Certes. Mais toute implémentation C aura une ou plusieurs limites (peu importent les valeurs d'icelles). Donc le compilateur sera bien obligé de faire l'évaluation A*B, justement pour le cas où est franchie la dite limite de l'implémentation.
(Sans compter qu'il est plus facile de faire le calcul A*B que d'avoir à gérer une table à je-ne-sais combien d'entrées, en fonction des types respectifs de A et B, pour déterminer si le résultat est négatif ou nul.)
Antoine
En news:20081117012443$236b@prunille.vinc17.org, Vincent Lefevre va
escriure:
Dans l'article <gfjqfj$g69$1@news.rd.francetelecom.fr>,
Michel Decima écrit:
Est-ce que c'est vrai pour toutes les valeurs de 16 ?
Oui, toutes celles où l'expression est bien définie (pas d'overflow).
<zap>
foo.c:3: warning: integer overflow in expression
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
foo.c:3: error: size of array 'tab' is negative
Cette erreur, c'est spécifique à l'implémentation, conséquence
de l'integer overflow.
Certes. Mais toute implémentation C aura une ou plusieurs limites (peu
importent les valeurs d'icelles).
Donc le compilateur sera bien obligé de faire l'évaluation A*B, justement
pour le cas où est franchie la dite limite de l'implémentation.
(Sans compter qu'il est plus facile de faire le calcul A*B que d'avoir à
gérer une table à je-ne-sais combien d'entrées, en fonction des types
respectifs de A et B, pour déterminer si le résultat est négatif ou nul.)
En news:20081117012443$, Vincent Lefevre va escriure:
Dans l'article <gfjqfj$g69$, Michel Decima écrit:
Est-ce que c'est vrai pour toutes les valeurs de 16 ?
Oui, toutes celles où l'expression est bien définie (pas d'overflow).
<zap>
foo.c:3: warning: integer overflow in expression
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
foo.c:3: error: size of array 'tab' is negative
Cette erreur, c'est spécifique à l'implémentation, conséquence de l'integer overflow.
Certes. Mais toute implémentation C aura une ou plusieurs limites (peu importent les valeurs d'icelles). Donc le compilateur sera bien obligé de faire l'évaluation A*B, justement pour le cas où est franchie la dite limite de l'implémentation.
(Sans compter qu'il est plus facile de faire le calcul A*B que d'avoir à gérer une table à je-ne-sais combien d'entrées, en fonction des types respectifs de A et B, pour déterminer si le résultat est négatif ou nul.)
Antoine
Antoine Leca
En news:20081114092411$, Vincent Lefevre va escriure:
Dans l'article <491cb231$0$8219$, Mickaël Wolff écrit:
Vincent Lefevre a écrit :
On peut très bien détecter le signe du résultat sans effectuer le produit!
En mathématique peut-être, mais en informatique pas forcément. Surtout pas avec les nombres signés. Sans le calculer, c'est difficile de savoir si (1 << 16) * 2 est positif ou négatif.
1 est un entier signé positif,
Oui
donc 1 << 16 est aussi positif, et de même que (1 << 16) * 2.
Pas forcément: cf. C99 6.1.3.1p3.
Rappel: il n'y a pas de wrapping sur les entiers signés.
Sur ta machine peut-être (cela fait partie des choses définies par l'implémentation, et je sais qu'il existe des machines à arithmétique entière avec saturation, surtout en QN), mais ce n'est pas commun.
Mais bon, il suffit que le signe soit détectable dans certains cas pour que dans ces cas-là, le compilateur ne soit pas obligé d'effectuer le calcul à la compilation.
Même si l'on effectue pas le calcul, cela reste une évaluation (au sens le plus commun du terme).
Antoine
En news:20081114092411$218c@prunille.vinc17.org, Vincent Lefevre va
escriure:
Dans l'article <491cb231$0$8219$426a74cc@news.free.fr>,
Mickaël Wolff écrit:
Vincent Lefevre a écrit :
On peut très bien détecter le signe du résultat sans effectuer le
produit!
En mathématique peut-être, mais en informatique pas forcément.
Surtout pas avec les nombres signés. Sans le calculer, c'est
difficile de savoir si (1 << 16) * 2 est positif ou négatif.
1 est un entier signé positif,
Oui
donc 1 << 16 est aussi positif, et de même que (1 << 16) * 2.
Pas forcément: cf. C99 6.1.3.1p3.
Rappel: il n'y a pas de wrapping sur les entiers signés.
Sur ta machine peut-être (cela fait partie des choses définies par
l'implémentation, et je sais qu'il existe des machines à arithmétique
entière avec saturation, surtout en QN), mais ce n'est pas commun.
Mais bon, il suffit que le signe soit détectable dans certains
cas pour que dans ces cas-là, le compilateur ne soit pas obligé
d'effectuer le calcul à la compilation.
Même si l'on effectue pas le calcul, cela reste une évaluation (au sens le
plus commun du terme).
En news:20081114092411$, Vincent Lefevre va escriure:
Dans l'article <491cb231$0$8219$, Mickaël Wolff écrit:
Vincent Lefevre a écrit :
On peut très bien détecter le signe du résultat sans effectuer le produit!
En mathématique peut-être, mais en informatique pas forcément. Surtout pas avec les nombres signés. Sans le calculer, c'est difficile de savoir si (1 << 16) * 2 est positif ou négatif.
1 est un entier signé positif,
Oui
donc 1 << 16 est aussi positif, et de même que (1 << 16) * 2.
Pas forcément: cf. C99 6.1.3.1p3.
Rappel: il n'y a pas de wrapping sur les entiers signés.
Sur ta machine peut-être (cela fait partie des choses définies par l'implémentation, et je sais qu'il existe des machines à arithmétique entière avec saturation, surtout en QN), mais ce n'est pas commun.
Mais bon, il suffit que le signe soit détectable dans certains cas pour que dans ces cas-là, le compilateur ne soit pas obligé d'effectuer le calcul à la compilation.
Même si l'on effectue pas le calcul, cela reste une évaluation (au sens le plus commun du terme).
Antoine
Vincent Lefevre
Dans l'article <gfs377$pc5$, Antoine Leca écrit:
En news:20081114092411$, Vincent Lefevre va escriure:
> donc 1 << 16 est aussi positif, et de même que (1 << 16) * 2.
Pas forcément: cf. C99 6.1.3.1p3.
N'existe pas ici.
> Rappel: il n'y a pas de wrapping sur les entiers signés.
Sur ta machine peut-être (cela fait partie des choses définies par l'implémentation, et je sais qu'il existe des machines à arithmétique entière avec saturation, surtout en QN),
J'entendais par là: il n'y a pas de wrapping garanti.
mais ce n'est pas commun.
Avec gcc, il faut -fwrapv pour qu'on soit sûr d'obtenir l'effet souhaité.
> Mais bon, il suffit que le signe soit détectable dans certains > cas pour que dans ces cas-là, le compilateur ne soit pas obligé > d'effectuer le calcul à la compilation.
Même si l'on effectue pas le calcul, cela reste une évaluation (au sens le plus commun du terme).
Le compilateur se comporte peut-être comme si c'était évalué (ça reste bien flou), mais cela ne veut pas dire qu'il codera en dur le résultat de l'évaluation.
Dans l'article <gfs377$pc5$1@shakotay.alphanet.ch>,
Antoine Leca <root@localhost.invalid> écrit:
En news:20081114092411$218c@prunille.vinc17.org, Vincent Lefevre va
escriure:
> donc 1 << 16 est aussi positif, et de même que (1 << 16) * 2.
Pas forcément: cf. C99 6.1.3.1p3.
N'existe pas ici.
> Rappel: il n'y a pas de wrapping sur les entiers signés.
Sur ta machine peut-être (cela fait partie des choses définies par
l'implémentation, et je sais qu'il existe des machines à arithmétique
entière avec saturation, surtout en QN),
J'entendais par là: il n'y a pas de wrapping garanti.
mais ce n'est pas commun.
Avec gcc, il faut -fwrapv pour qu'on soit sûr d'obtenir l'effet souhaité.
> Mais bon, il suffit que le signe soit détectable dans certains
> cas pour que dans ces cas-là, le compilateur ne soit pas obligé
> d'effectuer le calcul à la compilation.
Même si l'on effectue pas le calcul, cela reste une évaluation (au
sens le plus commun du terme).
Le compilateur se comporte peut-être comme si c'était évalué (ça reste
bien flou), mais cela ne veut pas dire qu'il codera en dur le résultat
de l'évaluation.
En news:20081114092411$, Vincent Lefevre va escriure:
> donc 1 << 16 est aussi positif, et de même que (1 << 16) * 2.
Pas forcément: cf. C99 6.1.3.1p3.
N'existe pas ici.
> Rappel: il n'y a pas de wrapping sur les entiers signés.
Sur ta machine peut-être (cela fait partie des choses définies par l'implémentation, et je sais qu'il existe des machines à arithmétique entière avec saturation, surtout en QN),
J'entendais par là: il n'y a pas de wrapping garanti.
mais ce n'est pas commun.
Avec gcc, il faut -fwrapv pour qu'on soit sûr d'obtenir l'effet souhaité.
> Mais bon, il suffit que le signe soit détectable dans certains > cas pour que dans ces cas-là, le compilateur ne soit pas obligé > d'effectuer le calcul à la compilation.
Même si l'on effectue pas le calcul, cela reste une évaluation (au sens le plus commun du terme).
Le compilateur se comporte peut-être comme si c'était évalué (ça reste bien flou), mais cela ne veut pas dire qu'il codera en dur le résultat de l'évaluation.
Je reformule la remarque de Mickael en remplacant le verbe "calculer":
"Sans verifier que l'expression est bien definie sur la plateforme cible (pas d'overflow), il est difficile de savoir si (1<<16)*2 est positif ou negatif."
Pas forcément. Ça dépend de la tête de l'expression. Par exemple, si a, b et c sont positifs et qu'il n'y a pas d'overflow ni comportement indéfini, alors (a << b) * c est positif. Un compilateur pourrait très bien avoir ce genre de règles (e.g. s'il est conçu pour des applications particulières...).
Je comprends bien que ce comportement est specifique a l'implementation, mais j'observe la meme chose sur toutes les plateformes auquel j'ai acces (linux/x86, hpux/ia64, aix/power). Evidemment, ca ne prouve rien pour les autres ;)
Je suis d'accord que ça reste théorique, mais on a parfois des timings surprenants.
Dans l'article <gfrcqf$oht$1@news.rd.francetelecom.fr>,
Michel Decima <michel.decima@orange-ft.com> écrit:
Je reformule la remarque de Mickael en remplacant le verbe "calculer":
"Sans verifier que l'expression est bien definie sur la plateforme cible
(pas d'overflow), il est difficile de savoir si (1<<16)*2 est positif
ou negatif."
Pas forcément. Ça dépend de la tête de l'expression. Par exemple, si
a, b et c sont positifs et qu'il n'y a pas d'overflow ni comportement
indéfini, alors (a << b) * c est positif. Un compilateur pourrait
très bien avoir ce genre de règles (e.g. s'il est conçu pour des
applications particulières...).
Je comprends bien que ce comportement est specifique a l'implementation,
mais j'observe la meme chose sur toutes les plateformes auquel j'ai
acces (linux/x86, hpux/ia64, aix/power). Evidemment, ca ne prouve rien
pour les autres ;)
Je suis d'accord que ça reste théorique, mais on a parfois des timings
surprenants.
Je reformule la remarque de Mickael en remplacant le verbe "calculer":
"Sans verifier que l'expression est bien definie sur la plateforme cible (pas d'overflow), il est difficile de savoir si (1<<16)*2 est positif ou negatif."
Pas forcément. Ça dépend de la tête de l'expression. Par exemple, si a, b et c sont positifs et qu'il n'y a pas d'overflow ni comportement indéfini, alors (a << b) * c est positif. Un compilateur pourrait très bien avoir ce genre de règles (e.g. s'il est conçu pour des applications particulières...).
Je comprends bien que ce comportement est specifique a l'implementation, mais j'observe la meme chose sur toutes les plateformes auquel j'ai acces (linux/x86, hpux/ia64, aix/power). Evidemment, ca ne prouve rien pour les autres ;)
Je suis d'accord que ça reste théorique, mais on a parfois des timings surprenants.
Donc le compilateur sera bien obligé de faire l'évaluation A*B, justement pour le cas où est franchie la dite limite de l'implémentation.
Pas obligé, même si c'est ce qui est le plus probable.
(Sans compter qu'il est plus facile de faire le calcul A*B que d'avoir à gérer une table à je-ne-sais combien d'entrées, en fonction des types respectifs de A et B, pour déterminer si le résultat est négatif ou nul.)
Pas forcément (e.g. avec une application particulière et un compilateur associé, où A et B ont des formes particulières).
Dans l'article <gfs285$jgq$1@shakotay.alphanet.ch>,
Antoine Leca <root@localhost.invalid> écrit:
Donc le compilateur sera bien obligé de faire l'évaluation A*B, justement
pour le cas où est franchie la dite limite de l'implémentation.
Pas obligé, même si c'est ce qui est le plus probable.
(Sans compter qu'il est plus facile de faire le calcul A*B que d'avoir à
gérer une table à je-ne-sais combien d'entrées, en fonction des types
respectifs de A et B, pour déterminer si le résultat est négatif ou nul.)
Pas forcément (e.g. avec une application particulière et un compilateur
associé, où A et B ont des formes particulières).
Donc le compilateur sera bien obligé de faire l'évaluation A*B, justement pour le cas où est franchie la dite limite de l'implémentation.
Pas obligé, même si c'est ce qui est le plus probable.
(Sans compter qu'il est plus facile de faire le calcul A*B que d'avoir à gérer une table à je-ne-sais combien d'entrées, en fonction des types respectifs de A et B, pour déterminer si le résultat est négatif ou nul.)
Pas forcément (e.g. avec une application particulière et un compilateur associé, où A et B ont des formes particulières).
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.1.3.1p3.
N'existe pas ici.
Exact, il fallait lire 6.3.1.3p3.
Le compilateur se comporte peut-être comme si c'était évalué (ça reste bien flou), mais cela ne veut pas dire qu'il codera en dur le résultat de l'évaluation.
Mais je n'ai jamais dit ni même sous-entendu qu'il n'était pas possible de (re)faire l'évaluation au moment de l'exécution. Voire même comme le proposait Marc, de faire trois évaluations distinctes et de choisir la plus « sûre ».
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]''.
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];
(et oui, je sais qu'en théorie C99 il y a des machines où INT_MAX+1u n'est PAS la moitié de UINT_MAX+1, dans ce cas merci de remplacer A dans l'expression ci-dessus par la puissance de 2 appropriée.)
Antoine
En news:20081117175312$32a2@prunille.vinc17.org, Vincent Lefevre va
escriure:
donc 1 << 16 est aussi positif, et de même que (1 << 16) * 2.
Pas forcément: cf. C99 6.1.3.1p3.
N'existe pas ici.
Exact, il fallait lire 6.3.1.3p3.
Le compilateur se comporte peut-être comme si c'était évalué (ça reste
bien flou), mais cela ne veut pas dire qu'il codera en dur le résultat
de l'évaluation.
Mais je n'ai jamais dit ni même sous-entendu qu'il n'était pas possible de
(re)faire l'évaluation au moment de l'exécution.
Voire même comme le proposait Marc, de faire trois évaluations distinctes et
de choisir la plus « sûre ».
Ton propos initial était de refuser l'argument de l'article
<gf9s85$rbc$1@registered.motzarella.org>, où Charlie Gordon
<news@chqrlie.org> é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]''.
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];
(et oui, je sais qu'en théorie C99 il y a des machines où INT_MAX+1u n'est
PAS la moitié de UINT_MAX+1, dans ce cas merci de remplacer A dans
l'expression ci-dessus par la puissance de 2 appropriée.)
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.1.3.1p3.
N'existe pas ici.
Exact, il fallait lire 6.3.1.3p3.
Le compilateur se comporte peut-être comme si c'était évalué (ça reste bien flou), mais cela ne veut pas dire qu'il codera en dur le résultat de l'évaluation.
Mais je n'ai jamais dit ni même sous-entendu qu'il n'était pas possible de (re)faire l'évaluation au moment de l'exécution. Voire même comme le proposait Marc, de faire trois évaluations distinctes et de choisir la plus « sûre ».
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]''.
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];
(et oui, je sais qu'en théorie C99 il y a des machines où INT_MAX+1u n'est PAS la moitié de UINT_MAX+1, dans ce cas merci de remplacer A dans l'expression ci-dessus par la puissance de 2 appropriée.)
Antoine
Vincent Lefevre
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.1.3.1p3. > > N'existe pas ici.
Exact, il fallait lire 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.
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]''.
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];
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. De telles expressions constantes peuvent alors très bien être évaluées à l'exécution.
Par exemple, pour A*B sur du non signé, on peut raisonner sur la valuation 2-adique.
Dans l'article <gg6svg$rle$1@shakotay.alphanet.ch>,
Antoine Leca <root@localhost.invalid> écrit:
En news:20081117175312$32a2@prunille.vinc17.org, Vincent Lefevre va
escriure:
>> donc 1 << 16 est aussi positif, et de même que (1 << 16) * 2.
>> Pas forcément: cf. C99 6.1.3.1p3.
>
> N'existe pas ici.
Exact, il fallait lire 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.
Ton propos initial était de refuser l'argument de l'article
<gf9s85$rbc$1@registered.motzarella.org>, où Charlie Gordon
<news@chqrlie.org> é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]''.
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];
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. De telles expressions constantes peuvent alors très
bien être évaluées à l'exécution.
Par exemple, pour A*B sur du non signé, on peut raisonner sur la
valuation 2-adique.
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.1.3.1p3. > > N'existe pas ici.
Exact, il fallait lire 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.
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]''.
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];
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. De telles expressions constantes peuvent alors très bien être évaluées à l'exécution.
Par exemple, pour A*B sur du non signé, on peut raisonner sur la valuation 2-adique.