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.
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.
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
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
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 <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).
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$,
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).
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.
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).
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.
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).
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.
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.
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.
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,
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.
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.
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.
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.
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.
> 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$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.
> 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:
> 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).
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."
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 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."
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 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."
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 ;)
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.)
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.)
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.)
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.
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.
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.
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.
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.
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: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.
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];
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.
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];
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.
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];