j'ai honte poser une question aussi basique
mais je ne dois pas avoir les yeux en face des trous
et je ne comprend pas ce qui ne va pas depuis plusieures heures :
Si on veut bien, au contraire de M. Bourguet, considérer que l'architecture des ordis n'est pas une simple vue de l'esprit, le fait est que les paramètres sont effectivement bien souvent semblables à des variables automatiques, par construction. Merci aux inventeurs du C de ne pas avoir tentés de faire croire le contraire !
Je suis d'accord.
-- Emmanuel The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html The C-library: http://www.dinkumware.com/refxc.html
"There are 10 types of people in the world today; those that understand binary, and those that dont."
cedric wrote on 25/03/05 :
Si on veut bien, au contraire de M. Bourguet, considérer que l'architecture
des ordis n'est pas une simple vue de l'esprit, le fait est que les
paramètres sont effectivement bien souvent semblables à des variables
automatiques, par construction. Merci aux inventeurs du C de ne pas avoir
tentés de faire croire le contraire !
Je suis d'accord.
--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html
"There are 10 types of people in the world today;
those that understand binary, and those that dont."
Si on veut bien, au contraire de M. Bourguet, considérer que l'architecture des ordis n'est pas une simple vue de l'esprit, le fait est que les paramètres sont effectivement bien souvent semblables à des variables automatiques, par construction. Merci aux inventeurs du C de ne pas avoir tentés de faire croire le contraire !
Je suis d'accord.
-- Emmanuel The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html The C-library: http://www.dinkumware.com/refxc.html
"There are 10 types of people in the world today; those that understand binary, and those that dont."
gregg
Emmanuel Delahaye wrote:
Je ne dois pas être aussi intégriste ou dogmatique que certains le prédentent, parce que je ne suis pas d'accord. La solution générale pour
Ces gens confondent peut-être "intégriste" et "puriste" ;-)
où l'utilisation du paramètre comme variable locale peut avoir un sens, notammet pour gagner un peu de place en mémoire automatique sur de petites fonctions simples et évoluant peu... (à l'occasion d'un refactoring, par exemple)
Je croyais que les paramètres étaient placés sur la pile. Qui est l'endroit de création des variables locales à une fonction. Non ?
Auquel cas, créer une variable locale en lui affectant la valeur du paramètre serait une perte d'espace et d'opérations. (je dis "perte" au sens de "redondant").
A ne pas mettre entre les mains des débutants complets[1]. Personnellement, je suis passé par le BASIC (un désastre), le Pascal (la Révélation), et quelques assembleurs (années 85/90...).
Pas d'Ada ? Ca me paraît bien pour commencer, Ada. Et si vraiment on ne veut pas continuer, le passage au C me paraît aisé.
++
Emmanuel Delahaye wrote:
Je ne dois pas être aussi intégriste ou dogmatique que certains le
prédentent, parce que je ne suis pas d'accord. La solution générale pour
Ces gens confondent peut-être "intégriste" et "puriste" ;-)
où l'utilisation du paramètre comme variable locale peut avoir un sens,
notammet pour gagner un peu de place en mémoire automatique sur de
petites fonctions simples et évoluant peu... (à l'occasion d'un
refactoring, par exemple)
Je croyais que les paramètres étaient placés sur la pile. Qui est
l'endroit de création des variables locales à une fonction.
Non ?
Auquel cas, créer une variable locale en lui affectant la valeur du
paramètre serait une perte d'espace et d'opérations.
(je dis "perte" au sens de "redondant").
A ne pas mettre entre les mains des débutants complets[1].
Personnellement, je suis passé par le BASIC (un désastre), le Pascal (la
Révélation), et quelques assembleurs (années 85/90...).
Pas d'Ada ?
Ca me paraît bien pour commencer, Ada.
Et si vraiment on ne veut pas continuer, le passage au C me paraît aisé.
Je ne dois pas être aussi intégriste ou dogmatique que certains le prédentent, parce que je ne suis pas d'accord. La solution générale pour
Ces gens confondent peut-être "intégriste" et "puriste" ;-)
où l'utilisation du paramètre comme variable locale peut avoir un sens, notammet pour gagner un peu de place en mémoire automatique sur de petites fonctions simples et évoluant peu... (à l'occasion d'un refactoring, par exemple)
Je croyais que les paramètres étaient placés sur la pile. Qui est l'endroit de création des variables locales à une fonction. Non ?
Auquel cas, créer une variable locale en lui affectant la valeur du paramètre serait une perte d'espace et d'opérations. (je dis "perte" au sens de "redondant").
A ne pas mettre entre les mains des débutants complets[1]. Personnellement, je suis passé par le BASIC (un désastre), le Pascal (la Révélation), et quelques assembleurs (années 85/90...).
Pas d'Ada ? Ca me paraît bien pour commencer, Ada. Et si vraiment on ne veut pas continuer, le passage au C me paraît aisé.
++
Emmanuel Delahaye
gregg wrote on 25/03/05 :
Pas d'Ada ?
Hélas non.
Ca me paraît bien pour commencer, Ada. Et si vraiment on ne veut pas continuer, le passage au C me paraît aisé.
Je pense que j'aurais bien aimé ça... Le Pascal (Turbo Pascal, bien sûr) a joué ce rôle de préparation à la rigueur.
-- Emmanuel The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html The C-library: http://www.dinkumware.com/refxc.html
I once asked an expert COBOL programmer, how to declare local variables in COBOL, the reply was: "what is a local variable?"
gregg wrote on 25/03/05 :
Pas d'Ada ?
Hélas non.
Ca me paraît bien pour commencer, Ada.
Et si vraiment on ne veut pas continuer, le passage au C me paraît aisé.
Je pense que j'aurais bien aimé ça... Le Pascal (Turbo Pascal, bien
sûr) a joué ce rôle de préparation à la rigueur.
--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html
I once asked an expert COBOL programmer, how to
declare local variables in COBOL, the reply was:
"what is a local variable?"
En quoi est-ce un abus dans la mesure où le paramètre de toutes les façons garde sa valeur initiale (c'est à dire à l'entrée dans la fonction), puisque passé par valeur ?
vous préconisez plutôt ça, alors:
unsigned fac (unsigned n) { unsigned tmp = n, f=1; while ( tmp > 1 ) f *= tmp--; return f; }
En quoi est-ce un abus dans la mesure où le paramètre de toutes les
façons garde sa valeur initiale (c'est à dire à l'entrée dans la
fonction), puisque passé par valeur ?
vous préconisez plutôt ça, alors:
unsigned fac (unsigned n) {
unsigned tmp = n, f=1;
while ( tmp > 1 ) f *= tmp--;
return f;
}
En quoi est-ce un abus dans la mesure où le paramètre de toutes les façons garde sa valeur initiale (c'est à dire à l'entrée dans la fonction), puisque passé par valeur ?
vous préconisez plutôt ça, alors:
unsigned fac (unsigned n) { unsigned tmp = n, f=1; while ( tmp > 1 ) f *= tmp--; return f; }
Tout à fait. Ca serait tellement plus propre si C faisait la distinction entre paramètre et variable locale, et s'il interdisait de réassigner un paramètre (si le paramètre est déclaré comme T* param, il devrait interdire de réassigner param mais bien sûr permettre d'assigner *param).. Ca serait cohérent avec la sémantique de passage d'argument, et ça éviterait des erreurs stupides comme celle à l'origine de cette discussion.
Je ne dois pas être aussi intégriste ou dogmatique que certains le prédentent, parce que je ne suis pas d'accord. La solution générale pour préserver la valeur des paramètres est de les qualifier avec 'const' comme je l'ai déjà exposé. Mais il est des cas rares, mais qui existent où l'utilisation du paramètre comme variable locale peut avoir un sens, notammet pour gagner un peu de place en mémoire automatique sur de petites fonctions simples et évoluant peu... (à l'occasion d'un refactoring, par exemple)
Un bon compilateur doit être capable d'optimiser void f(int i) { int tmp = i; faire_qque_chose_avec_tmp; } en void f(int i) { faire_qque_chose_avec_i; }
Le problème à l'origine de cette discussion vient **uniquement** du fait que le C autorise à réassigner aa (voir l'exemple initial). Si le langage interdisait de traiter les paramètres comme des variables (au sens litéral du terme), le langage serait plus "naturel" et ce genre de confusion n'arriverait pas.
D'une manière plus générale, ce n'est pas parce deux concepts sont implémentés de la même manière (paramètres et variables locales sont tous les 2 alloués sur la pile), qu'il ne faut pas les différencier. Il y a souvent des raisons "sémantiques" qui justifient qu'on les différencie.
Une partie des défauts du C vient de ce genre de focalisation excessive sur l'implémentation, au détriment de la sémantique. L'absence de type booléen en est un autre bon exemple. Le raisonnement est en gros le suivant : les tests booléens sont implémentés comme des tests à zéro, donc on peut considérer que toute valeur non nulle est vraie, et donc on n'a pas besoin d'un type booléen).
D'un point de vue sémantique, un paramètre passé par valeur n'est pas une variable, et un pointeur non nul n'est pas la valeur booléenne true. Au niveau de l'implémentation, ces différences s'estompent, mais elles ont pourtant un intérêt car elles rendent le langage plus expressif et plus sûr.
La question n'est donc pas honteuse, ce sont les designers de langage qui devraient avoir honte!
Non. Le C reste un modèle d'efficacité et de compacité. Mais comme je le rappelle souvent:
Ici, ma critique visait surtout Java et C#. Le C et le C++ doivent maintenir des compatibilités "historiques" et ça serait difficile à changer (mais on pourrait avoir une option de compilation pour contrôler ça). Les designers de Java et C# auraient pu faire un effort et corriger ce problème de sémantique des paramètres (heureusement, ils ont quand même pensé à introduire un type booléen).
D'un autre côté, je ne devrais pas me plaindre, il m'est arrivé de gagner une bouteille de champagne en pariant avec un programmeur Java (pas vraiment débutant mais qui devait avoir l'esprit embrumé) qu'une réaffectation de paramètre était sans effet sur le code appelant ;-)
Bruno.
"C is a sharp tool"
A ne pas mettre entre les mains des débutants complets[1]. Personnellement, je suis passé par le BASIC (un désastre), le Pascal (la Révélation), et quelques assembleurs (années 85/90...).
------------- [1] Je précise pour les ânes qui ne savent pas lire...
-- Emmanuel The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html The C-library: http://www.dinkumware.com/refxc.html
"Mal nommer les choses c'est ajouter du malheur au monde." -- Albert Camus.
"Emmanuel Delahaye" <emdel@YOURBRAnoos.fr> a écrit dans le message de news:
mn.cc1b7d5394e8df66.15512@YOURBRAnoos.fr...
Tout à fait. Ca serait tellement plus propre si C faisait la distinction
entre paramètre et variable locale, et s'il interdisait de réassigner un
paramètre (si le paramètre est déclaré comme T* param, il devrait
interdire de réassigner param mais bien sûr permettre d'assigner
*param).. Ca serait cohérent avec la sémantique de passage d'argument, et
ça éviterait des erreurs stupides comme celle à l'origine de cette
discussion.
Je ne dois pas être aussi intégriste ou dogmatique que certains le
prédentent, parce que je ne suis pas d'accord. La solution générale pour
préserver la valeur des paramètres est de les qualifier avec 'const' comme
je l'ai déjà exposé. Mais il est des cas rares, mais qui existent où
l'utilisation du paramètre comme variable locale peut avoir un sens,
notammet pour gagner un peu de place en mémoire automatique sur de petites
fonctions simples et évoluant peu... (à l'occasion d'un refactoring, par
exemple)
Un bon compilateur doit être capable d'optimiser
void f(int i) { int tmp = i; faire_qque_chose_avec_tmp; }
en
void f(int i) { faire_qque_chose_avec_i; }
Le problème à l'origine de cette discussion vient **uniquement** du fait que
le C autorise à réassigner aa (voir l'exemple initial). Si le langage
interdisait de traiter les paramètres comme des variables (au sens litéral
du terme), le langage serait plus "naturel" et ce genre de confusion
n'arriverait pas.
D'une manière plus générale, ce n'est pas parce deux concepts sont
implémentés de la même manière (paramètres et variables locales sont tous
les 2 alloués sur la pile), qu'il ne faut pas les différencier. Il y a
souvent des raisons "sémantiques" qui justifient qu'on les différencie.
Une partie des défauts du C vient de ce genre de focalisation excessive sur
l'implémentation, au détriment de la sémantique. L'absence de type booléen
en est un autre bon exemple. Le raisonnement est en gros le suivant : les
tests booléens sont implémentés comme des tests à zéro, donc on peut
considérer que toute valeur non nulle est vraie, et donc on n'a pas besoin
d'un type booléen).
D'un point de vue sémantique, un paramètre passé par valeur n'est pas une
variable, et un pointeur non nul n'est pas la valeur booléenne true. Au
niveau de l'implémentation, ces différences s'estompent, mais elles ont
pourtant un intérêt car elles rendent le langage plus expressif et plus sûr.
La question n'est donc pas honteuse, ce sont les designers de langage qui
devraient avoir honte!
Non. Le C reste un modèle d'efficacité et de compacité. Mais comme je le
rappelle souvent:
Ici, ma critique visait surtout Java et C#. Le C et le C++ doivent maintenir
des compatibilités "historiques" et ça serait difficile à changer (mais on
pourrait avoir une option de compilation pour contrôler ça). Les designers
de Java et C# auraient pu faire un effort et corriger ce problème de
sémantique des paramètres (heureusement, ils ont quand même pensé à
introduire un type booléen).
D'un autre côté, je ne devrais pas me plaindre, il m'est arrivé de gagner
une bouteille de champagne en pariant avec un programmeur Java (pas vraiment
débutant mais qui devait avoir l'esprit embrumé) qu'une réaffectation de
paramètre était sans effet sur le code appelant ;-)
Bruno.
"C is a sharp tool"
A ne pas mettre entre les mains des débutants complets[1].
Personnellement, je suis passé par le BASIC (un désastre), le Pascal (la
Révélation), et quelques assembleurs (années 85/90...).
-------------
[1] Je précise pour les ânes qui ne savent pas lire...
--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html
"Mal nommer les choses c'est ajouter du malheur au
monde." -- Albert Camus.
Tout à fait. Ca serait tellement plus propre si C faisait la distinction entre paramètre et variable locale, et s'il interdisait de réassigner un paramètre (si le paramètre est déclaré comme T* param, il devrait interdire de réassigner param mais bien sûr permettre d'assigner *param).. Ca serait cohérent avec la sémantique de passage d'argument, et ça éviterait des erreurs stupides comme celle à l'origine de cette discussion.
Je ne dois pas être aussi intégriste ou dogmatique que certains le prédentent, parce que je ne suis pas d'accord. La solution générale pour préserver la valeur des paramètres est de les qualifier avec 'const' comme je l'ai déjà exposé. Mais il est des cas rares, mais qui existent où l'utilisation du paramètre comme variable locale peut avoir un sens, notammet pour gagner un peu de place en mémoire automatique sur de petites fonctions simples et évoluant peu... (à l'occasion d'un refactoring, par exemple)
Un bon compilateur doit être capable d'optimiser void f(int i) { int tmp = i; faire_qque_chose_avec_tmp; } en void f(int i) { faire_qque_chose_avec_i; }
Le problème à l'origine de cette discussion vient **uniquement** du fait que le C autorise à réassigner aa (voir l'exemple initial). Si le langage interdisait de traiter les paramètres comme des variables (au sens litéral du terme), le langage serait plus "naturel" et ce genre de confusion n'arriverait pas.
D'une manière plus générale, ce n'est pas parce deux concepts sont implémentés de la même manière (paramètres et variables locales sont tous les 2 alloués sur la pile), qu'il ne faut pas les différencier. Il y a souvent des raisons "sémantiques" qui justifient qu'on les différencie.
Une partie des défauts du C vient de ce genre de focalisation excessive sur l'implémentation, au détriment de la sémantique. L'absence de type booléen en est un autre bon exemple. Le raisonnement est en gros le suivant : les tests booléens sont implémentés comme des tests à zéro, donc on peut considérer que toute valeur non nulle est vraie, et donc on n'a pas besoin d'un type booléen).
D'un point de vue sémantique, un paramètre passé par valeur n'est pas une variable, et un pointeur non nul n'est pas la valeur booléenne true. Au niveau de l'implémentation, ces différences s'estompent, mais elles ont pourtant un intérêt car elles rendent le langage plus expressif et plus sûr.
La question n'est donc pas honteuse, ce sont les designers de langage qui devraient avoir honte!
Non. Le C reste un modèle d'efficacité et de compacité. Mais comme je le rappelle souvent:
Ici, ma critique visait surtout Java et C#. Le C et le C++ doivent maintenir des compatibilités "historiques" et ça serait difficile à changer (mais on pourrait avoir une option de compilation pour contrôler ça). Les designers de Java et C# auraient pu faire un effort et corriger ce problème de sémantique des paramètres (heureusement, ils ont quand même pensé à introduire un type booléen).
D'un autre côté, je ne devrais pas me plaindre, il m'est arrivé de gagner une bouteille de champagne en pariant avec un programmeur Java (pas vraiment débutant mais qui devait avoir l'esprit embrumé) qu'une réaffectation de paramètre était sans effet sur le code appelant ;-)
Bruno.
"C is a sharp tool"
A ne pas mettre entre les mains des débutants complets[1]. Personnellement, je suis passé par le BASIC (un désastre), le Pascal (la Révélation), et quelques assembleurs (années 85/90...).
------------- [1] Je précise pour les ânes qui ne savent pas lire...
-- Emmanuel The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html The C-library: http://www.dinkumware.com/refxc.html
"Mal nommer les choses c'est ajouter du malheur au monde." -- Albert Camus.
En quoi est-ce un abus dans la mesure où le paramètre de toutes les façons garde sa valeur initiale (c'est à dire à l'entrée dans la fonction), puisque passé par valeur ?
vous préconisez plutôt ça, alors:
unsigned fac (unsigned n) { unsigned tmp = n, f=1; while ( tmp > 1 ) f *= tmp--; return f; }
En quoi est-ce un abus dans la mesure où le paramètre de toutes les
façons garde sa valeur initiale (c'est à dire à l'entrée dans la
fonction), puisque passé par valeur ?
vous préconisez plutôt ça, alors:
unsigned fac (unsigned n) {
unsigned tmp = n, f=1;
while ( tmp > 1 ) f *= tmp--;
return f;
}
En quoi est-ce un abus dans la mesure où le paramètre de toutes les façons garde sa valeur initiale (c'est à dire à l'entrée dans la fonction), puisque passé par valeur ?
vous préconisez plutôt ça, alors:
unsigned fac (unsigned n) { unsigned tmp = n, f=1; while ( tmp > 1 ) f *= tmp--; return f; }