OVH Cloud OVH Cloud

parametres simples en const ?

70 réponses
Avatar
JBB
Bonjour

Lorsque je crée une fonction qui prend un entier en paramètre je fais quelque chose du genre:

int Double( int x)
{
return 2*x;
}

Je me demande s'il il n'est pas plus sage de faire
int Double( const int x)
{
return 2*x;
}
dans la mesure ou je n'ai pas l'intention de modifier x dans le corps.

Cela permettrait d'eviter certaines erreurs (comme affecter x par erreur), par exemple :
int Rapport(const int a,const int b)
{
bool bDivisionParZero = ( b = 0);
if (bDivisionParZero )
{
//exception
}
else
{
return a / b;
}
}
Si b est declare const ce code ne compile pas.
ou alors
int rapport(const int nombreElements,Truc * Tableau)
{
for (;nombreElements >0; nombreElements--)
{
...
}

//renvoyer le nombre d'elements traites
return nombreElements;
}

Est ce une pratique courrante?

10 réponses

1 2 3 4 5
Avatar
Marc Boyer
Le 03-03-2006, JBB a écrit :
Bonjour

Lorsque je crée une fonction qui prend un entier en paramètre je fais quelque chose du genre:

int Double( int x)
{
return 2*x;
}

Je me demande s'il il n'est pas plus sage de faire
int Double( const int x)
{
return 2*x;
}
dans la mesure ou je n'ai pas l'intention de modifier x dans le corps.


On pourrait, mais le problème est que ce const apparaît dans la
signature de la fonction alors que c'est une question d'implantation.

Cela permettrait d'eviter certaines erreurs (comme affecter x par erreur), par exemple :
[SNIP l'exemple]


Sont-elle si fréquentes ?

Est ce une pratique courrante?


Pas que je sache. Au contraire, il est (fut?) assez populaire en
C de réutiliser les paramètres pour éviter des copies inutiles.

Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exiter des sots
IF -- Rudyard Kipling (Trad. Paul Éluard)

Avatar
Sylvain
JBB wrote on 03/03/2006 11:16:
Bonjour

Lorsque je crée une fonction qui prend un entier en paramètre je fais
quelque chose du genre:
[..]
Je me demande s'il il n'est pas plus sage de faire
int Double( const int x)
{
return 2*x;
}


devrait lire return 2.0 * x;
(et se coder directement (x << 1))

Cela permettrait d'eviter certaines erreurs (comme affecter x par
erreur), par exemple :
int Rapport(const int a,const int b)
{
bool bDivisionParZero = ( b = 0);


devrait lire divisionParZero = (b == 0);

}
Si b est declare const ce code ne compile pas.


du à l'erreur ci avant.

Est ce une pratique courrante?


cela devrait être systématique.

Sylvain.

Avatar
Marc Boyer
Le 03-03-2006, Sylvain a écrit :
JBB wrote on 03/03/2006 11:16:
Bonjour

Lorsque je crée une fonction qui prend un entier en paramètre je fais
quelque chose du genre:
[..]
Je me demande s'il il n'est pas plus sage de faire
int Double( const int x)
{
return 2*x;
}


devrait lire return 2.0 * x;


Et pourquoi ce passage en double ?

(et se coder directement (x << 1))


Sur ?

Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exiter des sots
IF -- Rudyard Kipling (Trad. Paul Éluard)


Avatar
EjderHa

Je me demande s'il il n'est pas plus sage de faire

int Double( const int x) { return 2*x; }

dans la mesure ou je n'ai pas l'intention de modifier x dans le corps.


oui si tu est un inconditionnel de la programmation défensive.
Personnelement je ne vois pas vraiment la différence, de toute
manière pour un paramètre passez par valeur on travail avec une copie
dans la pile.

Moi j'en profite pour éviter de déclarer d'autres variables locales
les paramètres faisant déjà l'affaire. (dans un parcourt de tableau
par exemple).

int sum (int T[], int n)
{
int r = 0; while (n>0) r += T[--n];
return r;
}

C'est juste une petite optimisation pour éviter d'utiliser une case
d'entier supplementaire dans la pile, mais ca sert surtout pour des
fonctions hautement récursives. Dans cet example y'a pas vraiment
d'interet, les compilos auront vite fait de tranformer l'appel en bloc
inline utilisant juste des registres et pas la pile.


Cela permettrait d'eviter certaines erreurs (comme affecter x par erreur)


et alors tu l'affecte mais à part l'occurence de l'execution de ta
fonction personne n'est au courant, tant que c'est un passage de
paramètre par valeur tu n'a rien à craindre. Si tu commence à jouer
avec les références alors là oui, il faut faire attention. c'est pas
pour rien qu'un constructeur de recopie utilise "const Type&", ou les
fonctions friend d'une classe (operator<< par example)

C'est dommage que le constante ne se propage pas à travers les
pointeurs et les structures, car on ne serait pas tres loin d'une
véritable sémantique de recopie, pour les classes encapsulés par
exemple.


int Rapport(const int a,const int b)
{
bool bDivisionParZero = ( b = 0);
if (bDivisionParZero )
{
//exception
}
else
{
return a / b;
}
}
Si b est declare const ce code ne compile pas.


ton bool bDivisionParZero faudrait peut-etre le remplacer par (b==0),
et la ca devrait compiler (en rajouter la levée de l'exception). sinon
oui tu affecte 0 à b que t'a déclaré comme variable locale
constante. il faut savoir ce que tu veut une constante ou pas
constante, faut faire un choix.
sans le constante tu te retrouve ici avec du code mort, les warnings du
compilo c'est pas juste pour remplir la sortie d'erreur standard. il
faut les lires ça permet de savoir ou tu fait des fautes.

pour résumer, le mots clef const est plus un élément de programation
défensive, c'est une manière simple de rajouter de la sémantique aux
variables. (pour c++ que l'élément déclarer comme const ne soit pas
utilisé en left side d'une affectation)

mais ca sert pour des variables globales, pour des pointeurs vers
constante, ou des références vers constante. Je ne vois pas
l'interêt pratique de mettre un paramètre simple en const.

Avatar
Marc Duflot
Marc Boyer wrote:

Bonjour

Lorsque je crée une fonction qui prend un entier en paramètre je fais quelque chose du genre:

int Double( int x)
{
return 2*x;
}

Je me demande s'il il n'est pas plus sage de faire
int Double( const int x)
{
return 2*x;
}
dans la mesure ou je n'ai pas l'intention de modifier x dans le corps.



On pourrait, mais le problème est que ce const apparaît dans la
signature de la fonction alors que c'est une question d'implantation.


Non, il est permis (et conseillé) de déclarer dans l'interface

int Double (int x);

et d'utiliser dans la définition

int Double (const int x)
{
return 2*x;
}

Dans les interfaces, il ne devrait jamais y avoir de const à cet endroit.


Avatar
TERENCE
"EjderHa" a écrit dans le message de news:


int Rapport(const int a,const int b)
{
bool bDivisionParZero = ( b = 0);
if (bDivisionParZero )


ton bool bDivisionParZero faudrait peut-etre le remplacer par (b==0),
et la ca devrait compiler (en rajouter la levée de l'exception). sinon



Mais c'est peut-etre le but recherché : etre averti lorsque l'on se trompe par mégarde entre l'affectation et la comparaison.


oui tu affecte 0 à b que t'a déclaré comme variable locale
constante. il faut savoir ce que tu veut une constante ou pas
constante, faut faire un choix.
sans le constante tu te retrouve ici avec du code mort, les warnings du
compilo c'est pas juste pour remplir la sortie d'erreur standard. il
faut les lires ça permet de savoir ou tu fait des fautes.



Avatar
Marc Boyer
Le 03-03-2006, Marc Duflot a écrit :
Marc Boyer wrote:
On pourrait, mais le problème est que ce const apparaît dans la
signature de la fonction alors que c'est une question d'implantation.


Non, il est permis (et conseillé) de déclarer dans l'interface

int Double (int x);

et d'utiliser dans la définition

int Double (const int x)
{
return 2*x;
}


Je ne savais pas. Merci de l'information.
Au cas où, sais-tu si c'est spécifique C++ ou si C
admet la même chose ?

Dans les interfaces, il ne devrait jamais y avoir de const à cet endroit.


C'est bien ce qu'il me semblait.

Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exiter des sots
IF -- Rudyard Kipling (Trad. Paul Éluard)


Avatar
Aurélien Barbier-Accary
Le 03-03-2006, Marc Duflot a écrit :
Non, il est permis (et conseillé) de déclarer dans l'interface
int Double (int x);
et d'utiliser dans la définition
int Double (const int x)
{
return 2*x;
}




const int i = 3;
cout << "le double de " << i << " est " << Double(i) << endl;

-> un bon compilateur doit signaler un warning !!
Moi je plaide pour :
int Double(const int x);
ça fonctionne avec int et avec const int

Aurélien.


Avatar
Jean-Marc Bourguet
Aurélien Barbier-Accary writes:

Le 03-03-2006, Marc Duflot a écrit :
Non, il est permis (et conseillé) de déclarer dans l'interface
int Double (int x);
et d'utiliser dans la définition
int Double (const int x)
{
return 2*x;
}




const int i = 3;
cout << "le double de " << i << " est " << Double(i) << endl;

-> un bon compilateur doit signaler un warning !!


Pourquoi?

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org



Avatar
Marc Duflot
Marc Boyer wrote:

Non, il est permis (et conseillé) de déclarer dans l'interface

int Double (int x);

et d'utiliser dans la définition

int Double (const int x)
{
return 2*x;
}



Au cas où, sais-tu si c'est spécifique C++ ou si C
admet la même chose ?


Je n'ai pas de certitude pour le C. Un essai avec deux compilateurs C en
mode intransigeant me laisse penser que c'est le cas mais pour être sûr,
mieux vaut demander à côté.


1 2 3 4 5