Ai-je une quelconque garantie que l'expression A*B ne sera pas réévaluée à chaque tour de boucle pendant l'exécution ?
Non. Cependant en pratique A*B sera évalué à la compilation.
Je dirais même plus : on peut être quasi-sûr que ce sera le cas, pour 2 raisons: - 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]''. - si d'aventure ce n'était pas le cas, le résultat serait quand même 10, le donc programme fonctionnerait correctement, et le manque de performance dû à cette lacune du compilo serait le cadet de tes soucis, le code généré pour le reste du programme étant vraisemblablement tout aussi inefficace.
Si tu as des doutes, tu peux toujours écrire
for (i = 0; i < sizeof(char[A * B]); i++) ...
Mais c'est un style particulièrement laid.
-- Chqrlie.
"Erwan David" <erwan@rail.eu.org> a écrit dans le message de news:
m21vxkkb7s.fsf@ratagaz.depot.rail.eu.org...
candide <candide@free.invalid> écrivait :
Bonjour,
La norme dit :
6.6 Constant expressions
(...)
A constant expression can be evaluated during translation rather than
runtime,
Ai-je une quelconque garantie que l'expression A*B ne sera pas réévaluée
à chaque tour de boucle pendant l'exécution ?
Non. Cependant en pratique A*B sera évalué à la compilation.
Je dirais même plus : on peut être quasi-sûr que ce sera le cas, pour 2
raisons:
- 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]''.
- si d'aventure ce n'était pas le cas, le résultat serait quand même 10, le
donc programme fonctionnerait correctement, et le manque de performance dû à
cette lacune du compilo serait le cadet de tes soucis, le code généré pour
le reste du programme étant vraisemblablement tout aussi inefficace.
Ai-je une quelconque garantie que l'expression A*B ne sera pas réévaluée à chaque tour de boucle pendant l'exécution ?
Non. Cependant en pratique A*B sera évalué à la compilation.
Je dirais même plus : on peut être quasi-sûr que ce sera le cas, pour 2 raisons: - 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]''. - si d'aventure ce n'était pas le cas, le résultat serait quand même 10, le donc programme fonctionnerait correctement, et le manque de performance dû à cette lacune du compilo serait le cadet de tes soucis, le code généré pour le reste du programme étant vraisemblablement tout aussi inefficace.
Si tu as des doutes, tu peux toujours écrire
for (i = 0; i < sizeof(char[A * B]); i++) ...
Mais c'est un style particulièrement laid.
-- Chqrlie.
Wykaaa
candide a écrit :
Bonjour,
La norme dit :
6.6 Constant expressions (...) A constant expression can be evaluated during translation rather than runtime,
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
Un compilateur qui génèrerait du code pour réévaluer A*B a chaque tour de boucle, il vaut mieux l'abandonner tout de suite parce que c'est trivial à faire comme optimisation.
candide a écrit :
Bonjour,
La norme dit :
6.6 Constant expressions
(...)
A constant expression can be evaluated during translation rather than
runtime,
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
Un compilateur qui génèrerait du code pour réévaluer A*B a chaque tour
de boucle, il vaut mieux l'abandonner tout de suite parce que c'est
trivial à faire comme optimisation.
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
Un compilateur qui génèrerait du code pour réévaluer A*B a chaque tour de boucle, il vaut mieux l'abandonner tout de suite parce que c'est trivial à faire comme optimisation.
Antoine Leca
En news:49172a5f$0$17384$, candide va escriure:
#include <stdio.h> #define A 2 #define B 5 int main(void) { int i; for (i = 0; i < A * B; i++) printf("toton"); 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 ?
Garantie formelle, non. D'ailleurs, tu n'as pas non plus de garantie que le compilateur ou le processeur ne fasse pas 5 additions du nombre 2 à chaque tour de boucle (tu as seulement la garantie qu'il ne va /pas/ passer par une adition des logarithmes de 2 et de 5); tu n'as même pas de garantie qu'il y ait effectivement une boucle.
J'ai déjà vu des compilateurs (pas C, mais c'est un détail) qui remplaçait à la compilation le programme ci-dessus par
int main(void) { puts("totontotontotontotontotontotontotontotontotontoto"); return 0; }
Plus de i, plus de printf et un seul appel... Alors l'évaluation du produit A*B, à ce niveau, c'est un détail de l'histoire...
En C, je ne pense pas que l'on rencontre de compilateur qui va sucrer printf(), même si la norme le permet, parce qu'il est entré dans les mours de pouvoir remplacer à l'édition des liens les fonctions de bibliothèque en général, et malloc/free ou printf en particulier. Par contre, les compilateurs optimisateurs vont dérouler la boucle, et réécrire le programme ci-dessus sous la forme int printf(const char*, ...); int main(void) { printf("toton"); printf("toton"); printf("toton"); printf("toton"); printf("toton"); printf("toton"); printf("toton"); printf("toton"); printf("toton"); printf("toton"); return 0; } Et à partir de là, comme les compilateurs d'aujourd'hui ont des capacités d'analyser les chaînes de format, il doit être possible de trouver un compilateur qui vont fusionner les 10 chaînes de format entre elles, et arriver à int printf(const char*, ...); int main(void) { printf("totontotontotontotontotontotontotontotontotontoton"); return 0; }
Antoine
En news:49172a5f$0$17384$426a74cc@news.free.fr, candide va escriure:
#include <stdio.h>
#define A 2
#define B 5
int main(void) {
int i;
for (i = 0; i < A * B; i++) printf("toton");
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 ?
Garantie formelle, non. D'ailleurs, tu n'as pas non plus de garantie que le
compilateur ou le processeur ne fasse pas 5 additions du nombre 2 à chaque
tour de boucle (tu as seulement la garantie qu'il ne va /pas/ passer par une
adition des logarithmes de 2 et de 5); tu n'as même pas de garantie qu'il y
ait effectivement une boucle.
J'ai déjà vu des compilateurs (pas C, mais c'est un détail) qui remplaçait à
la compilation le programme ci-dessus par
int main(void) {
puts("totontotontotontotontotontotontotontotontotontoto");
return 0; }
Plus de i, plus de printf et un seul appel... Alors l'évaluation du produit
A*B, à ce niveau, c'est un détail de l'histoire...
En C, je ne pense pas que l'on rencontre de compilateur qui va sucrer
printf(), même si la norme le permet, parce qu'il est entré dans les mours
de pouvoir remplacer à l'édition des liens les fonctions de bibliothèque en
général, et malloc/free ou printf en particulier. Par contre, les
compilateurs optimisateurs vont dérouler la boucle, et réécrire le programme
ci-dessus sous la forme
int printf(const char*, ...);
int main(void) {
printf("toton"); printf("toton"); printf("toton"); printf("toton");
printf("toton"); printf("toton"); printf("toton");
printf("toton"); printf("toton"); printf("toton");
return 0; }
Et à partir de là, comme les compilateurs d'aujourd'hui ont des capacités
d'analyser les chaînes de format, il doit être possible de trouver un
compilateur qui vont fusionner les 10 chaînes de format entre elles, et
arriver à
int printf(const char*, ...);
int main(void) {
printf("totontotontotontotontotontotontotontotontotontoton");
return 0; }
#include <stdio.h> #define A 2 #define B 5 int main(void) { int i; for (i = 0; i < A * B; i++) printf("toton"); 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 ?
Garantie formelle, non. D'ailleurs, tu n'as pas non plus de garantie que le compilateur ou le processeur ne fasse pas 5 additions du nombre 2 à chaque tour de boucle (tu as seulement la garantie qu'il ne va /pas/ passer par une adition des logarithmes de 2 et de 5); tu n'as même pas de garantie qu'il y ait effectivement une boucle.
J'ai déjà vu des compilateurs (pas C, mais c'est un détail) qui remplaçait à la compilation le programme ci-dessus par
int main(void) { puts("totontotontotontotontotontotontotontotontotontoto"); return 0; }
Plus de i, plus de printf et un seul appel... Alors l'évaluation du produit A*B, à ce niveau, c'est un détail de l'histoire...
En C, je ne pense pas que l'on rencontre de compilateur qui va sucrer printf(), même si la norme le permet, parce qu'il est entré dans les mours de pouvoir remplacer à l'édition des liens les fonctions de bibliothèque en général, et malloc/free ou printf en particulier. Par contre, les compilateurs optimisateurs vont dérouler la boucle, et réécrire le programme ci-dessus sous la forme int printf(const char*, ...); int main(void) { printf("toton"); printf("toton"); printf("toton"); printf("toton"); printf("toton"); printf("toton"); printf("toton"); printf("toton"); printf("toton"); printf("toton"); return 0; } Et à partir de là, comme les compilateurs d'aujourd'hui ont des capacités d'analyser les chaînes de format, il doit être possible de trouver un compilateur qui vont fusionner les 10 chaînes de format entre elles, et arriver à int printf(const char*, ...); int main(void) { printf("totontotontotontotontotontotontotontotontotontoton"); return 0; }
Antoine
Jean-Marc Bourguet
"Antoine Leca" writes:
En news:49172a5f$0$17384$, candide va escriure:
#include <stdio.h> #define A 2 #define B 5 int main(void) { int i; for (i = 0; i < A * B; i++) printf("toton"); 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 ?
Garantie formelle, non. D'ailleurs, tu n'as pas non plus de garantie que le compilateur ou le processeur ne fasse pas 5 additions du nombre 2 à chaque tour de boucle (tu as seulement la garantie qu'il ne va /pas/ passer par une adition des logarithmes de 2 et de 5); tu n'as même pas de garantie qu'il y ait effectivement une boucle.
J'ai déjà vu des compilateurs (pas C, mais c'est un détail) qui remplaçait à la compilation le programme ci-dessus par
int main(void) { puts("totontotontotontotontotontotontotontotontotontoto"); return 0; }
Plus de i, plus de printf et un seul appel... Alors l'évaluation du produit A*B, à ce niveau, c'est un détail de l'histoire...
(Mais si je l'ai déjà vu supprimer du code mort ou remplacer des appels à des fonctions standard par d'autres comme ici, je ne l'ai pas encore vu fusionner des appels).
A+
-- Jean-Marc FAQ de fclc: http://www.levenez.com/lang/c/faq Site de usenet-fr: http://www.usenet-fr.news.eu.org
"Antoine Leca" <root@localhost.invalid> writes:
En news:49172a5f$0$17384$426a74cc@news.free.fr, candide va escriure:
#include <stdio.h>
#define A 2
#define B 5
int main(void) {
int i;
for (i = 0; i < A * B; i++) printf("toton");
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 ?
Garantie formelle, non. D'ailleurs, tu n'as pas non plus de garantie que le
compilateur ou le processeur ne fasse pas 5 additions du nombre 2 à chaque
tour de boucle (tu as seulement la garantie qu'il ne va /pas/ passer par une
adition des logarithmes de 2 et de 5); tu n'as même pas de garantie qu'il y
ait effectivement une boucle.
J'ai déjà vu des compilateurs (pas C, mais c'est un détail) qui remplaçait à
la compilation le programme ci-dessus par
int main(void) {
puts("totontotontotontotontotontotontotontotontotontoto");
return 0; }
Plus de i, plus de printf et un seul appel... Alors l'évaluation du produit
A*B, à ce niveau, c'est un détail de l'histoire...
(Mais si je l'ai déjà vu supprimer du code mort ou remplacer des appels à
des fonctions standard par d'autres comme ici, je ne l'ai pas encore vu
fusionner des appels).
A+
--
Jean-Marc
FAQ de fclc: http://www.levenez.com/lang/c/faq
Site de usenet-fr: http://www.usenet-fr.news.eu.org
#include <stdio.h> #define A 2 #define B 5 int main(void) { int i; for (i = 0; i < A * B; i++) printf("toton"); 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 ?
Garantie formelle, non. D'ailleurs, tu n'as pas non plus de garantie que le compilateur ou le processeur ne fasse pas 5 additions du nombre 2 à chaque tour de boucle (tu as seulement la garantie qu'il ne va /pas/ passer par une adition des logarithmes de 2 et de 5); tu n'as même pas de garantie qu'il y ait effectivement une boucle.
J'ai déjà vu des compilateurs (pas C, mais c'est un détail) qui remplaçait à la compilation le programme ci-dessus par
int main(void) { puts("totontotontotontotontotontotontotontotontotontoto"); return 0; }
Plus de i, plus de printf et un seul appel... Alors l'évaluation du produit A*B, à ce niveau, c'est un détail de l'histoire...
(Mais si je l'ai déjà vu supprimer du code mort ou remplacer des appels à des fonctions standard par d'autres comme ici, je ne l'ai pas encore vu fusionner des appels).
A+
-- Jean-Marc FAQ de fclc: http://www.levenez.com/lang/c/faq Site de usenet-fr: http://www.usenet-fr.news.eu.org
Vincent Lefevre
Dans l'article <gf9s85$rbc$, 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]''.
Euh... A * B pourrait très bien être effectué au lancement du programme (même si ce n'est pas le cas en pratique).
Dans l'article <gf9s85$rbc$1@registered.motzarella.org>,
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]''.
Euh... A * B pourrait très bien être effectué au lancement du
programme (même si ce n'est pas le cas en pratique).
Dans l'article <gf9s85$rbc$, 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]''.
Euh... A * B pourrait très bien être effectué au lancement du programme (même si ce n'est pas le cas en pratique).
En news:20081113150454$, Vincent Lefevre va escriure:
Dans l'article <gf9s85$rbc$, 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]''.
Euh... A * B pourrait très bien être effectué au lancement du programme
Non. Si A*B donne une résultat négatif ou nul, le compilateur doit émettre un diagnostic, ce qui impose de faire l'évaluation.
Antoine
En news:20081113150454$2719@prunille.vinc17.org, Vincent Lefevre va
escriure:
Dans l'article <gf9s85$rbc$1@registered.motzarella.org>,
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]''.
Euh... A * B pourrait très bien être effectué au lancement du
programme
Non. Si A*B donne une résultat négatif ou nul, le compilateur doit émettre
un diagnostic, ce qui impose de faire l'évaluation.
En news:20081113150454$, Vincent Lefevre va escriure:
Dans l'article <gf9s85$rbc$, 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]''.
Euh... A * B pourrait très bien être effectué au lancement du programme
Non. Si A*B donne une résultat négatif ou nul, le compilateur doit émettre un diagnostic, ce qui impose de faire l'évaluation.
Antoine
Vincent Lefevre
Dans l'article <gfhpuk$vvu$, Antoine Leca écrit:
En news:20081113150454$, Vincent Lefevre va escriure: > Dans l'article <gf9s85$rbc$, > 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]''. > > Euh... A * B pourrait très bien être effectué au lancement du > programme
Non. Si A*B donne une résultat négatif ou nul, le compilateur doit émettre un diagnostic, ce qui impose de faire l'évaluation.
On peut très bien détecter le signe du résultat sans effectuer le produit!
Dans l'article <gfhpuk$vvu$1@shakotay.alphanet.ch>,
Antoine Leca <root@localhost.invalid> écrit:
En news:20081113150454$2719@prunille.vinc17.org, Vincent Lefevre va
escriure:
> Dans l'article <gf9s85$rbc$1@registered.motzarella.org>,
> 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]''.
>
> Euh... A * B pourrait très bien être effectué au lancement du
> programme
Non. Si A*B donne une résultat négatif ou nul, le compilateur doit émettre
un diagnostic, ce qui impose de faire l'évaluation.
On peut très bien détecter le signe du résultat sans effectuer le
produit!
En news:20081113150454$, Vincent Lefevre va escriure: > Dans l'article <gf9s85$rbc$, > 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]''. > > Euh... A * B pourrait très bien être effectué au lancement du > programme
Non. Si A*B donne une résultat négatif ou nul, le compilateur doit émettre un diagnostic, ce qui impose de faire l'évaluation.
On peut très bien détecter le signe du résultat sans effectuer le produit!
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.
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.
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.
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. Le compilateur peut aussi émettre un diagnostic s'il estime que certains calculs sont trop compliqué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.
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. Le compilateur peut aussi
émettre un diagnostic s'il estime que certains calculs sont trop
compliqué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.
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. Le compilateur peut aussi émettre un diagnostic s'il estime que certains calculs sont trop compliqués.