 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
David F. Guest
|
Posted: Sat Oct 15, 2005 11:04 am Post subject: const & sur les POD |
|
|
Bonjour,
je lis parfois le code suivant (un poste récent le montre d'ailleurs):
1. int fct( const INT& n );
au lieu d'un simple
2. int fct ( INT n );
L'argument pour la forme 1. est (à mon sens):
- elle force la vérification que n ne sera pas
modifiée à l'intérieur de fct.
- elle force un passage sans recopie de n
( plus génant pour un vrai objet)
- elle évité d'avoir à réfléchir si INT est un POD ou un objet
complexe et hésiter entre la forme 1. et 2.
Honnêtement, même si j'utilise la forme 2. pour les POD, et la 1.
pour les objets. J'ai du mal à donner des arguments contre la forme 1
(au delà de la lourdeur de la notation).
Cordialement.
|
|
| Back to top |
|
 |
Stan Guest
|
Posted: Sat Oct 15, 2005 12:37 pm Post subject: Re: const & sur les POD |
|
|
----- Original Message -----
From: "David F." <dfleury2 (AT) libertysurf (DOT) fr>
Newsgroups: fr.comp.lang.c++
Sent: Saturday, October 15, 2005 1:04 PM
Subject: const & sur les POD
| Quote: | Bonjour,
je lis parfois le code suivant (un poste récent le montre d'ailleurs):
1. int fct( const INT& n );
au lieu d'un simple
2. int fct ( INT n );
L'argument pour la forme 1. est (à mon sens):
- elle force la vérification que n ne sera pas
modifiée à l'intérieur de fct.
|
Oui.
| Quote: | - elle force un passage sans recopie de n
( plus génant pour un vrai objet)
|
Plus génant ?
Au contraire passer un objet par référence offre un gain :
pas de construction ni de destruction de l'objet.
| Quote: | - elle évité d'avoir à réfléchir si INT est un POD ou un objet
complexe et hésiter entre la forme 1. et 2.
|
Il n'y a pas a hésiter puisque la première
forme est préférable ( sauf pour les types de base comme int ou double ).
| Quote: | Honnêtement, même si j'utilise la forme 2. pour les POD, et la 1.
pour les objets. J'ai du mal à donner des arguments contre la forme 1
(au delà de la lourdeur de la notation).
|
La "lourdeur de la notation" est largement compensée
par les avantages offerts.
--
-Stan
|
|
| Back to top |
|
 |
Franck Branjonneau Guest
|
Posted: Sat Oct 15, 2005 1:02 pm Post subject: Re: const & sur les POD |
|
|
"David F." <dfleury2 (AT) libertysurf (DOT) fr> écrivait:
| Quote: | 1. int fct( const INT& n );
2. int fct ( INT n );
Honnêtement, même si j'utilise la forme 2. pour les POD, et la 1.
pour les objets.
|
Un POD est un objet -- enfin une instance d'un type POD est un objet...
Tu mélanges constance et passage par valeur ou par référence. Si n est
constant dans le corps de la fonction alors tu utilises 1 ou
3. int fct(INT const n);
Sinon tu utilises 2 ou
4. int fonc(INT& n);
Tu utilises le passage par référence si tu en as besoin pour le
typage dynamique ou si l'objet est gros (pour une définition ad hoc de
gros).
--
Franck Branjonneau <fasbjx (AT) free (DOT) fr>
|
|
| Back to top |
|
 |
Vincent Lascaux Guest
|
Posted: Sat Oct 15, 2005 8:18 pm Post subject: Re: const & sur les POD |
|
|
| Quote: | Tu utilises le passage par référence si tu en as besoin pour le
typage dynamique ou si l'objet est gros (pour une définition ad hoc de
gros).
|
Est ce que le compilateur a le droit de modifier un passage par référence
const en un passage par valeur ?
En gros, si c'est plus rapide d'appeler
int foo(int i) { return i+1; }
que
int foo(const int& i) { return i+1; }
mais qu'on écrit quand même la deuxième forme (une bonne raison de faire ca
serait que foo est une fonction template, qu'on a écrit const T& parceque T
peut être très lourd à copier, et qu'on utilise foo<int>), est ce que le
compilo est en droit d'utiliser la premiere version ? Est ce qu'en pratique
les compilos le font ?
--
Vincent
|
|
| Back to top |
|
 |
David F. Guest
|
Posted: Sat Oct 15, 2005 8:29 pm Post subject: Re: const & sur les POD |
|
|
Stan a écrit :
| Quote: | ----- Original Message -----
From: "David F."
Bonjour,
je lis parfois le code suivant (un poste récent le montre d'ailleurs):
1. int fct( const INT& n );
au lieu d'un simple
2. int fct ( INT n );
L'argument pour la forme 1. est (à mon sens):
- elle force la vérification que n ne sera pas
modifiée à l'intérieur de fct.
Oui.
- elle force un passage sans recopie de n
( plus génant pour un vrai objet)
Plus génant ?
Au contraire passer un objet par référence offre un gain :
pas de construction ni de destruction de l'objet.
|
Quand je disais "( plus génant pour un vrai objet)"
je parlais de la recopie.
| Quote: |
- elle évité d'avoir à réfléchir si INT est un POD ou un objet
complexe et hésiter entre la forme 1. et 2.
Il n'y a pas a hésiter puisque la première
forme est préférable ( sauf pour les types de base comme int ou double ).
Honnêtement, même si j'utilise la forme 2. pour les POD, et la 1.
pour les objets. J'ai du mal à donner des arguments contre la forme 1
(au delà de la lourdeur de la notation).
La "lourdeur de la notation" est largement compensée
par les avantages offerts.
--
-Stan
|
|
|
| Back to top |
|
 |
David F. Guest
|
Posted: Sat Oct 15, 2005 9:14 pm Post subject: Re: const & sur les POD |
|
|
Franck Branjonneau a écrit :
| Quote: | "David F." <dfleury2 (AT) libertysurf (DOT) fr> écrivait:
1. int fct( const INT& n );
2. int fct ( INT n );
Honnêtement, même si j'utilise la forme 2. pour les POD, et la 1.
pour les objets.
Un POD est un objet -- enfin une instance d'un type POD est un objet...
|
Oui erreur de terme désolé, je voulais parler des types
fondamentaux ou primitifs ( int, float, double, ... ).
| Quote: | Tu mélanges constance et passage par valeur ou par référence. Si n est
constant dans le corps de la fonction alors tu utilises 1 ou
3. int fct(INT const n);
|
Je ne pense pas mélanger.
La forme 3 n'a pas l'avantage (événtuel) de ne passer qu'un
pointeur lors de l'appel de la fonction, ni d'éviter une recopie
pour les instances d'objets complexes.
(en plus d'être ignoré ou au pire signalé en warning car inutile)
| Quote: | Sinon tu utilises 2 ou
4. int fonc(INT& n);
Tu utilises le passage par référence si tu en as besoin pour le
typage dynamique ou si l'objet est gros (pour une définition ad hoc de
gros).
|
En fait, ça je le sais déjà.
Ce n'était pas tout à fait le sens de ma question.
Je n'arriverais décidément jamais à me faire comprendre
par écrit :(
Je retente ma chance avec une source externe.
Le sujet tourne autour du point 25 de "C++ Coding Standards"
Je traduis (enfin j'essaye) un cours etrait:
"Pour les paramètres en entrée seulement:
- toujours "const" qualifier les pointeurs ou références qui
ne seront pas modifiés
- préférer la copie pour les types primitives et ceux à faible
coût de copie ( Point, complex<float>, ... ) -> forme 2
- conséder le passage par valeur au lieu du passage par référence
si la fonction nécessite une copie de cet argument.
(équivalent à const + référence + création de la variable temporaire).
-> disons forme 2'
Pour les paramètres en sortie ou entrée/sortie:
- préférer les pointeurs pour les arguments optionnels, ou sauvegarde
une copie du pointeur, ou manipule le responsable du pointé.
- préférer une référence pour les arguments obligatoires (non soumis
aux points précédents)"
(Merci à Sutter et Alexandrescu)
Mon problème (et uniquement celui là) est que j'ai du mal
à justifié la forme 2 ou la forme 2' par rapport à la solution
tout "const &"
J'espère que c'est plus clair malgré ma traduction maladroite
(le mieux c'est d'avoir l'original sous les yeux, ou même la version
française qui est sortie )
|
|
| Back to top |
|
 |
James Kanze Guest
|
Posted: Sat Oct 15, 2005 10:18 pm Post subject: Re: const & sur les POD |
|
|
Vincent Lascaux wrote:
| Quote: | Tu utilises le passage par référence si tu en as besoin pour
le typage dynamique ou si l'objet est gros (pour une
définition ad hoc de gros).
Est ce que le compilateur a le droit de modifier un passage
par référence const en un passage par valeur ?
|
Le compilateur a droit à faire tout ce qui ne modifie pas le
comportement visible du programme. S'il peut déterminer que le
résultat en est le même, il peut faire la modification.
| Quote: | En gros, si c'est plus rapide d'appeler
int foo(int i) { return i+1; }
que
int foo(const int& i) { return i+1; }
mais qu'on écrit quand même la deuxième forme (une bonne
raison de faire ca serait que foo est une fonction template,
qu'on a écrit const T& parceque T peut être très lourd à
copier, et qu'on utilise foo<int>), est ce que le compilo est
en droit d'utiliser la premiere version ?
|
Oui, à condition que ça ne modifie pas le comportement visible
(d'un programme légal).
À peu près la seule façon que ça pourrait modifier le
comportement visible, c'est si la fonction faisait un
const_cast, et modifiait en fait le paramètre. À partir de ce
moment, en revanche, l'appel de la fonction avec un objet const
ou avec un rvalue menerait à un comportement indéfini.
| Quote: | Est ce qu'en pratique les compilos le font ?
|
Sauf dans le cas des fonctions inline, je crois que cette
optimisation doit être extrèmement rare. Dans la pratique, les
compilateurs utilisent la même forme de l'appel partout. Il
faudrait donc où que le compilateur sache à chaque endroit d'un
appel qu'il n'y a pas de const_cast dans la fonction, soit que
le compilateur puisse voir un appel avec un rvalue ou un objet
const, et savoir qu'il puisse en voir un à chaque endroit de
l'appel.
--
James Kanze mailto: [email]james.kanze (AT) free (DOT) fr[/email]
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
|
|
| Back to top |
|
 |
Franck Branjonneau Guest
|
Posted: Sun Oct 16, 2005 6:23 pm Post subject: Re: const & sur les POD |
|
|
"David F." <dfleury2 (AT) libertysurf (DOT) fr> écrivait:
| Quote: | - préférer la copie pour les types primitives et ceux à faible
coût de copie ( Point, complex<float>, ... ) -> forme 2
- conséder le passage par valeur au lieu du passage par référence
si la fonction nécessite une copie de cet argument.
(équivalent à const + référence + création de la variable temporaire).
-> disons forme 2'
Mon problème (et uniquement celui là) est que j'ai du mal
à justifié la forme 2 ou la forme 2' par rapport à la solution
tout "const &"
|
Pour la forme 2 c'est parce que utiliser des valeurs laisse, à priori,
plus d'opportunités au compilateur de générer du code plus efficient.
Pour la forme 2' c'est une question de responsabilité. Si j'ai
struct S { S(const &) { throw "anything"; } };
int main() { S s; foo(s); }
Que se passe-t-il avec
void foo(S const & p) { S s(p); }
et avec
void foo(S p) { }
?
--
Franck Branjonneau <fasbjx (AT) free (DOT) fr>
|
|
| Back to top |
|
 |
David F. Guest
|
Posted: Sun Oct 16, 2005 9:20 pm Post subject: Re: const & sur les POD |
|
|
Franck Branjonneau a écrit :
| Quote: | "David F." <dfleury2 (AT) libertysurf (DOT) fr> écrivait:
- préférer la copie pour les types primitives et ceux à faible
coût de copie ( Point, complex<float>, ... ) -> forme 2
- considérer le passage par valeur au lieu du passage par référence
si la fonction nécessite une copie de cet argument.
(équivalent à const + référence + création de la variable temporaire).
-> disons forme 2'
Mon problème (et uniquement celui là) est que j'ai du mal
à justifié la forme 2 ou la forme 2' par rapport à la solution
tout "const &"
Pour la forme 2 c'est parce que utiliser des valeurs laisse, à priori,
plus d'opportunités au compilateur de générer du code plus efficient.
Pour la forme 2' c'est une question de responsabilité. Si j'ai
struct S {
|
s() {}
| Quote: | S(const &) { throw "anything"; } };
int main() { S s; foo(s); }
Que se passe-t-il avec
void foo(S const & p) { S s(p); }
et avec
void foo(S p) { }
?
|
Je dirai que ça throw pour les deux.
un exemple d'utilisation de la forme 2' pourrait être
une fonction trim ne modifiant par l'argument.
par exemple :
std::string trim( const std::string& s )
{
std::string tmp( s );
// trim tmp ...
return tmp;
}
la forme 2' donnerait :
std::string trim( std::string tmp )
{
// trim tmp ...
return tmp;
}
// on remarquera que la forme 2' n'est pas recommandée par Martin Fowler
// qui conseille de ne pas modifier les arguments en entrée.
// si je ne m'abuse. ( Refactoring - Remove Assignments to Parameters ).
Ca ne m'aide pas vraiment pour justifier l'emploi de l'une
ou l'autre des "formes".
void SetSomeBoolFlag( bool theFlag );
ou
void SetSomeBoolFlag( const bool& theFlag );
// ou void SetSomeBoolFlag( bool const & theFlag );
|
|
| Back to top |
|
 |
Franck Branjonneau Guest
|
Posted: Sun Oct 16, 2005 10:35 pm Post subject: Re: const & sur les POD |
|
|
"David F." <dfleury2 (AT) libertysurf (DOT) fr> écrivait:
| Quote: | Pour la forme 2' c'est une question de responsabilité. Si j'ai
struct S {
s() {}
S(const &) { throw "anything"; } };
int main() { S s; foo(s); }
Que se passe-t-il avec void foo(S const & p) { S s(p); }
et avec void foo(S p) { }
?
Je dirai que ça throw pour les deux.
|
Oui mais dans le premier cas c'est l'appelé qui lance l'exception alors
que dans le second cas c'est l'appelant.
| Quote: | un exemple d'utilisation de la forme 2' pourrait être
une fonction trim ne modifiant par l'argument.
par exemple :
std::string trim( const std::string& s )
{
try { |
| Quote: | std::string tmp( s );
|
} catch(...) {
throw;
}
| Quote: | // trim tmp ...
return tmp;
}
la forme 2' donnerait :
std::string trim( std::string tmp )
{
// trim tmp ...
return tmp;
}
Ca ne m'aide pas vraiment pour justifier l'emploi de l'une
ou l'autre des "formes".
void SetSomeBoolFlag( bool theFlag );
ou
void SetSomeBoolFlag( const bool& theFlag );
// ou void SetSomeBoolFlag( bool const & theFlag );
|
Ici, c'est le cas 1. Tu choisis le passage par valeur.
--
Franck Branjonneau <fasbjx (AT) free (DOT) fr>
|
|
| Back to top |
|
 |
Vincent Lascaux Guest
|
Posted: Mon Oct 17, 2005 3:35 am Post subject: Re: const & sur les POD |
|
|
"Franck Branjonneau" <fasbjx (AT) free (DOT) fr> a écrit dans le message de news:
[email]87slv1hyzl.fsf (AT) alpha (DOT) tchume.net[/email]...
| Quote: | "David F." <dfleury2 (AT) libertysurf (DOT) fr> écrivait:
Pour la forme 2' c'est une question de responsabilité. Si j'ai
struct S {
Je dirai que ça throw pour les deux.
Oui mais dans le premier cas c'est l'appelé qui lance l'exception alors
que dans le second cas c'est l'appelant.
|
Est ce qu'on peut être sur de ca ? Le compilo n'est il pas en droit
d'inliner ?
--
Vincent
|
|
| Back to top |
|
 |
David F. Guest
|
Posted: Mon Oct 17, 2005 6:20 am Post subject: Re: const & sur les POD |
|
|
Franck Branjonneau a écrit :
| Quote: | Ca ne m'aide pas vraiment pour justifier l'emploi de l'une
ou l'autre des "formes".
void SetSomeBoolFlag( bool theFlag );
ou
void SetSomeBoolFlag( const bool& theFlag );
// ou void SetSomeBoolFlag( bool const & theFlag );
Ici, c'est le cas 1. Tu choisis le passage par valeur.
|
Oui, mais pourquoi ?
Je n'arrive pas à le justifier à des programmeurs
qui viennent d'apprendre la notion de const &
qui l'utilise tout le temps.
|
|
| Back to top |
|
 |
Franck Branjonneau Guest
|
Posted: Mon Oct 17, 2005 9:51 pm Post subject: Re: const & sur les POD |
|
|
"Vincent Lascaux" <nospam (AT) nospam (DOT) org> écrivait:
| Quote: | "Franck Branjonneau" <fasbjx (AT) free (DOT) fr> a écrit dans le message de news:
[email]87slv1hyzl.fsf (AT) alpha (DOT) tchume.net[/email]...
"David F." <dfleury2 (AT) libertysurf (DOT) fr> écrivait:
Pour la forme 2' c'est une question de responsabilité. Si j'ai
struct S {
Je dirai que ça throw pour les deux.
Oui mais dans le premier cas c'est l'appelé qui lance l'exception alors
que dans le second cas c'est l'appelant.
Est ce qu'on peut être sur de ca ?
|
Oui.
| Quote: | Le compilo n'est il pas en droit d'inliner ?
|
Message-ID: <4351803f$0$21699$626a54ce (AT) news (DOT) free.fr>
Le compilateur a droit à faire tout ce qui ne modifie pas le
comportement visible du programme. S'il peut déterminer que le
résultat en est le même, il peut faire la modification.
Essaie
void foo(S const p) { std::cout << "In foon"; }
void foo(S const & p) { std::cout << "In foon"; S s(p); }
pour t'en persuader.
--
Franck Branjonneau
|
|
| Back to top |
|
 |
Franck Branjonneau Guest
|
Posted: Mon Oct 17, 2005 9:51 pm Post subject: Re: const & sur les POD |
|
|
"David F." <dfleury2 (AT) libertysurf (DOT) fr> écrivait:
| Quote: | Franck Branjonneau a écrit :
Ca ne m'aide pas vraiment pour justifier l'emploi de l'une
ou l'autre des "formes".
void SetSomeBoolFlag( bool theFlag );
ou
void SetSomeBoolFlag( const bool& theFlag );
// ou void SetSomeBoolFlag( bool const & theFlag );
Ici, c'est le cas 1. Tu choisis le passage par valeur.
Oui, mais pourquoi ?
|
Message-ID: <87oe5p9v90.fsf (AT) alpha (DOT) tchume.net>
Pour la forme 2 c'est parce que utiliser des valeurs laisse, à priori,
plus d'opportunités au compilateur de générer du code plus efficient.
--
Franck Branjonneau <fasbjx (AT) free (DOT) fr>
|
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
Posted: Mon Oct 17, 2005 10:52 pm Post subject: Re: const & sur les POD |
|
|
On Mon, 17 Oct 2005 23:51:47 +0200, Franck Branjonneau
<fasbjx (AT) free (DOT) fr>:
| Quote: | Message-ID: <87oe5p9v90.fsf (AT) alpha (DOT) tchume.net
|
Je t'encourage mettre "news:" après le "<" -- certains lecteurs de
news ont du mal s'il n'est pas là.
---> <news:87oe5p9v90.fsf (AT) alpha (DOT) tchume.net>
(Enfin, moi ça m'est égal, Agent s'en sort parfaitement )
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|