OVH Cloud OVH Cloud

Position de const

60 réponses
Avatar
Jmr
Bonjour, je voudrais écrire une fonction copiant le contenu d'un tableau
dans un autre. j'utilise la déclaration suivante :

bool Cpy(const float * & Source, float * & Dest)

En espérant que :
? & Source : passe le pointeur Source à la fonction en tant que référence
pour éviter une copie inutile (mais est-ce bien nécessaire ?)
? const float : évite de modifier la valeur du pointeur Source. (const
doit-il être placé là ou plutôt ici : float * const & Source ?)

Par la suite j'utilise une fonction déclarée ainsi :

bool Affect (const Data & src, Data & dest)

où :

Data est du genre :
struct Data
{
int n ;
float *p ;
} ;

Lorsque j'écris :
bool Affect (const Data & src, Data & dest)
{
Cpy(src.p, dest.p) ;
..
}

le compilateur affiche l'erreur suivante : error C2664: 'Cpy' : cannot
convert parameter 1 from 'float *const ' to 'const float *& '

j'en déduis que les qualificatifs const sont mal placés mais où faut'il les
placer ?

Par avance Merci

10 réponses

1 2 3 4 5
Avatar
Loïc Joly
Jmr wrote:
Bonjour, je voudrais écrire une fonction copiant le contenu d'un tableau
dans un autre. j'utilise la déclaration suivante :

bool Cpy(const float * & Source, float * & Dest)

En espérant que :
? & Source : passe le pointeur Source à la fonction en tant que référence
pour éviter une copie inutile (mais est-ce bien nécessaire ?)


Pas vraiment...

? const float : évite de modifier la valeur du pointeur Source. (const
doit-il être placé là ou plutôt ici : float * const & Source ?)


Telle qu'écrite, ta fonction promet juste de ne pas modifier les floats
pointés par Source. Le pointeur lui peut être modifié.

[...]

j'en déduis que les qualificatifs const sont mal placés mais où faut'il les
placer ?


Le cas général, c'est que const s'applique toujours à l'élément derrière
lequel il se trouve :

float const * -> pointeur sur des float constants
float * const -> pointeur constant sur des floats
float const * const -> pointeur constant sur un float constant
class C
{
void f() const; -> fonction constante
}

Le cas particulier, c'est que si cosnt est placé au début, il s'applique
à l'élément juste après lui :

const float * -> équivalent à float const *

Personnellement, quand j'écris du code , je me débrouille pour toujours
être dans le cas général, mais le cas particulier est aussi bon à
connaître (pour lire du code écrit par d'autres).

--
Loïc

Avatar
Jmr
Merci !
"Loïc Joly" a écrit dans le message de
news:bk1hho$23u$
Jmr wrote:
Bonjour, je voudrais écrire une fonction copiant le contenu d'un tableau
dans un autre. j'utilise la déclaration suivante :

bool Cpy(const float * & Source, float * & Dest)

En espérant que :
? & Source : passe le pointeur Source à la fonction en tant que
référence


pour éviter une copie inutile (mais est-ce bien nécessaire ?)


Pas vraiment...

? const float : évite de modifier la valeur du pointeur Source. (const
doit-il être placé là ou plutôt ici : float * const & Source ?)


Telle qu'écrite, ta fonction promet juste de ne pas modifier les floats
pointés par Source. Le pointeur lui peut être modifié.

[...]

j'en déduis que les qualificatifs const sont mal placés mais où faut'il
les


placer ?


Le cas général, c'est que const s'applique toujours à l'élément derrière
lequel il se trouve :

float const * -> pointeur sur des float constants
float * const -> pointeur constant sur des floats
float const * const -> pointeur constant sur un float constant
class C
{
void f() const; -> fonction constante
}

Le cas particulier, c'est que si cosnt est placé au début, il s'applique
à l'élément juste après lui :

const float * -> équivalent à float const *

Personnellement, quand j'écris du code , je me débrouille pour toujours
être dans le cas général, mais le cas particulier est aussi bon à
connaître (pour lire du code écrit par d'autres).

--
Loïc




Avatar
Michaël Monerau
Loïc Joly wrote:
Le cas particulier, c'est que si cosnt est placé au début, il
s'applique à l'élément juste après lui :

const float * -> équivalent à float const *

Personnellement, quand j'écris du code , je me débrouille pour
toujours être dans le cas général, mais le cas particulier est aussi
bon à connaître (pour lire du code écrit par d'autres).


Pourquoi ça serait un cas particulier ?
Moi, j'utilise cette notation et je la trouve plus clair, car on sait tout
de suite que c'est constant. Enfin, c'est plus une habitude en fait :)

Le float const* est-il mieux à utiliser ? C'est plus "clair" ? Est-ce que
ça vaut le coup que je change mon habitude ou c'est minime ?
--
<=- Michaël "Cortex" Monerau -=>

Avatar
Fabien LE LEZ
On Sun, 14 Sep 2003 13:48:15 GMT, "Michaël Monerau"
wrote:

Moi, j'utilise cette notation et je la trouve plus clair, car on sait tout
de suite que c'est constant.


C'est le "c'" qui me gêne : quand on a une expression un peu
compliquée, avec des pointeurs, on ne voit pas immédiatement si c'est
le pointeur ou le pointé qui est const.

Enfin, c'est plus une habitude en fait :)


C'est AMHA la seule raison pour laquelle ce cas particulier est
utilisé...

Le float const* est-il mieux à utiliser ? C'est plus "clair" ? Est-ce que
ça vaut le coup que je change mon habitude ou c'est minime ?


AMHA, ça ne vaut pas le coup que tu casses l'homogénéité d'un projet.
Pour un nouveau projet, par contre, ça peut valoir le coup d'améliorer
la lisibilité.

Avatar
Fabien LE LEZ
On Sun, 14 Sep 2003 15:41:53 GMT, "Michaël Monerau"
wrote:

const float a = 3; <=> float const a = 3;

Si oui, c'est pareil ? Il vaut mieux utiliser `float const' ?


Yep, histoire d'homogénéiser le tout.

Avatar
Michaël Monerau
Fabien LE LEZ wrote:
On Sun, 14 Sep 2003 15:44:10 GMT, "Michaël Monerau"
wrote:

Pourquoi les fonctions comme strcpy, etc...
prennent-elles des `const char*' ? Parce que c'est du C et qu'ils
préfèrent le `const char*' au `char const*' ?


Il me semble effectivement que les prototypes de ces fonctions est
hérité du C, d'où les "const char*".


OK. Merci pour les conseils ^^
--
<=- Michaël "Cortex" Monerau -=>


Avatar
James Kanze
Fabien LE LEZ writes:

|> > Enfin, c'est plus une habitude en fait :)

|> C'est AMHA la seule raison pour laquelle ce cas particulier est
|> utilisé...

N'empeche qu'il y a beaucoup de débuttants en C++ qui l'utilise. Des
gens qui n'ont pas encore d'habitude, d'une façon à d'autre.

La raison la plus fréquente pourquoi les gens l'adoptent, à mon
avis, c'est parce que c'est comme ça que Stroustrup (parmi d'autres)
écrit les déclarations. Or, même si j'ai une préférence
pour l'autre forme, je ne dirais pas que ceux qui font autrement ne
savent pas ce qu'ils font, étant donnés le niveau de certains qui
font autrement.

Mes règles : à l'intérieur d'un projet, soit cohérent. Au
début du projet, s'il y a une consensus, l'adopter comme règle. Si
on est au début d'un projet, et il n'y a pas de consensus, j'argue
pour ma façon. Quitte à utiliser l'autre forme, si c'est comme
ça que se développe le consensus.

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
Avatar
James Kanze
"Michaël Monerau" writes:

|> Fabien LE LEZ wrote:
|> >> Le float const* est-il mieux à utiliser ? C'est plus "clair"
|> >> ? Est-ce que ça vaut le coup que je change mon habitude ou
|> >> c'est minime ?

|> > AMHA, ça ne vaut pas le coup que tu casses
|> > l'homogénéité d'un projet. Pour un nouveau projet, par
|> > contre, ça peut valoir le coup d'améliorer la lisibilité.

|> Et une autre question. Pourquoi les fonctions comme strcpy, etc...
|> prennent-elles des `const char*' ? Parce que c'est du C et qu'ils
|> préfèrent le `const char*' au `char const*' ?

D'abord, qu'on soit clair : « char const* » ou « const char* »,
c'est la même chose. Que tu écris l'un ou l'autre, ça ne change
absolument rien à la signification de la declaration. Il s'agit
simplement d'un choix stylistique -- strcpy prend aussi bien « char
const* » que « const char* ».

Deuxièmement, ça n'a rien à faire avec du C ou du C++. Moi,
j'écris « char const* » même en C, et ça marche
exactement comme quand je l'écris en C++. N'oublions pas que dans la
norme C++ aussi, la forme utilisée est toujours « const char* ».

Enfin, quant aux raisons : la forme dans la norme reflette en fait rien
de plus que la préférence de l'éditeur -- celui qui a mis la
texte en sa forme finale. Dans le cas de C++, Andy Koenig.

Si tu adoptes la forme « char const* », tu suis l'exemple d'un
certain nombre d'experts : moi et Fabien, par exemple:-), mais aussi
David Vandevoorde, Francis Glassborow, etc. Sinon, tu suis l'exemple
d'un certain nombre d'experts aussi : Bjarne Stroustrup, Andy Koenig,
Scott Meyer, Herb Sutter...

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
Avatar
Gabriel Dos Reis
James Kanze writes:

| certain nombre d'experts : moi et Fabien, par exemple:-)

une canicule d'égocentrisme ? ;-)

[je crois que la form « usuelle » serait : Fabien et moi. Note la
place du « moi »]

-- Gaby
Avatar
Michaël Monerau
James Kanze wrote:
Moi, j'utilise cette notation et je la trouve plus clair, car on
sait tout de suite que c'est constant.



Et comment fais-tu en cas des fonctions const ? Des pointeurs const
(et non des pointeurs à const) ?


pour les fonctions const, je mets effectivement le const après le prototype
de fonction :

class A
{
public:
int GetNumber () const {return 1;}
};

C'est vrai que ce n'est pas cohérent avec ma façon (mon ancienne :p) de
noter les pointeurs.

Et pour les pointeurs const :
float * const pFloat;

mais je ne m'en suis encore jamais servi donc je n'ai pas vu cette
incohérence aussi.

Le problème avec ta règle, c'est que tu ne peux pas le suivre
systèmatiquement.


C'est vrai. Je vais donc adopter la "tienne".

Le float const* est-il mieux à utiliser ?



Certains le prétendent. Certains y insiste même très fort.
C'est la forme que je préfère aussi, parce qu'elle me semble plus
cohérente. En revanche, je reconnais que la cohérence, en
général, n'est pas un point fort du C++, et surtout, des
declarations en C++.


Ah, te demander pourquoi tu trouves une incohérence ne rentrerait pas dans
ce thread, mais ça m'intéresse quand même :)

C'est plus "clair" ?



Ce dont on a l'habitude est toujours plus clair. Si tu travailles dans
une équipe, la chose la plus importante, c'est que tout le monde fait
pareil.


Oui. Je n'ai pas (encore) d'équipe, et je vais adopter la notation "float
const*" dès maintenant. Elle permet aussi de voir tout de suite le type du
pointeur, avant de voir qu'il est const (ce qui ne change pas pour un "int
const*" par exemple).

Est-ce que ça vaut le coup que je change mon habitude ou c'est
minime ?



À mon avis, tôt ou tard, il va falloir que tu utilises les deux,
selon les équipes où tu te trouves. Personellement, j'ai trouvé
qu'une fois habitué aux deux, je préfère la forme float const*.
Beaucoup d'autres m'ont dit la même chose. Mais si tu as déjà
un corpus important de code, je ne dis pas qu'il faut le changer tout
de suite. Et surtout, je dirais qu'il vaut mieux que les deux formes
ne se trouvent pas tous les deux dans un même corpus de code.


En effet, je pense aussi qu'il faut être familiarisé avec les deux formes,
de sorte à pouvoir faire le choix qui nous plait le plus.
--
<=- Michaël "Cortex" Monerau -=>



1 2 3 4 5