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
kanze
"Michaël Monerau" wrote in message
news:<WL29b.132850$...
James Kanze wrote:


[...]
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 :)


Dans les incohérences générales, on pouvait commencer par le fait de
vouloir être « type safe » et de dériver de C ; il y a déjà une forte
contradiction. Sinon, la récherche des noms en est pleine -- la règle
qu'un nom dans une structure imbriquée cache le même nom dans une
structure qui le contient vaut pour les classes et les blocs, mais pas
pour les namespace, par exemple. Sans parler du fait que dans un
template, un nom dépendant fait l'objet de deux récherches à la place
d'une, qui partent chacune d'un contexte différent et qui utilisent des
règles différentes. Quant à la section §13.3 de la norme (la résolution
des surcharges), je n'ôserais pas dire que ce n'est pas cohérente, parce
que je n'y comprends rien, tellement c'est compliquée. Mais c'en a
l'air ; parfois le const joue une rôle, parfois non, par exemple.

Dans les incohérences qui concernent les declarations, commençons par le
fait que dans la spécification de la declaration, l'ordre est sans
signification, tandis que dans le declarator, si. Ou mieux : je peux
déclarer un int** et un int * const* dans la même declaration, mais non
un int** et un int const**. Sans parler de la signification de int[],
qui dépend d'où se trouve la déclaration.

Et puis, il y a l'exemple classique :

typedef int* pi ;
const pi cpi ;
qui n'est pas la même chose que :
const int* cpi ;

C'est l'une des motivations la plus souvent citée pour adopter la forme

typedef int* pi ;
pi const cpi ;
int *const cpi ;

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16


Avatar
Gabriel Dos Reis
writes:

| Sinon, la récherche des noms en est pleine -- la règle
| qu'un nom dans une structure imbriquée cache le même nom dans une
| structure qui le contient vaut pour les classes et les blocs, mais pas
| pour les namespace, par exemple.

??? peux-tu t'expliquer ?

-- Gaby
Avatar
Samuel Krempp
le Monday 15 September 2003 13:25, écrivit :

| de vue de la langue anglaise. Mais si on adopte la régle
| que les déclarations peuvent généralement déchiffré en
| les lisant de droite à gauche, la règle générale s'impose.

comme "unsigned int typedef size_t" ?


ça encore, on peut répondre que c'est particulier, typedef
je penserais plutôt à des trucs comme

double (*f) (double);

qui est plus épineux pour qqun qui aime les choses simples.
(et c'est pour ça que xavier a préciser généralement j'imagine)

--
Sam

Avatar
Gabriel Dos Reis
Samuel Krempp writes:

| > comme "unsigned int typedef size_t" ?
|
| ça encore, on peut répondre que c'est particulier, typedef

Hmm. Donc vous avez la règle complètement fausse. La règle généra le
est que les déclarations se lisent « innermost to outermost ».

que dire de

void (*f(int (&)[8]))(const int&)

?

-- Gaby
Avatar
Samuel Krempp
le Monday 15 September 2003 13:47, écrivit :

Et puis, il y a l'exemple classique :

typedef int* pi ;
const pi cpi ;
qui n'est pas la même chose que :
const int* cpi ;

C'est l'une des motivations la plus souvent citée pour adopter la forme

typedef int* pi ;
pi const cpi ;
int *const cpi ;


on pourrait faire un préprocesseur qui utilise 2 caractères unicode de
parenthèses spéciales (pour les distinguer des autres), pour permettre une
syntaxe parenthesée de déclarations, et alors les 2 notations seraient du
meme acabit (là je vais écrire des { }, car je n'ai pas de caractère
unicode adéquat et le forum rejette les messages unicode de tte façon..) :

typedef int* pi;
const pi cpi;
const {int *} cpi2=cpi;
{const int} * pci;
avec cette syntaxe, le const irait très bien devant, en harmonie avec la
syntaxe et la prononciation (constant pointer to int ou pointer to
constant int).

évidemment, cette syntaxe parenthèsée est imaginaire, alors que que
celle spécifiée par le C++ est bien réelle.
mais je crois que je passe par une syntaxe dans ce genre mentalement quand
je lis des déclarations, alors je ne partage pas cette motivation de mettre
const derrière.

enfin bref, ce n'est pas juste par rapport à la syntaxe que le const
derrière ou devant est plus ou moins naturel, c'est aussi lié à la façon de
la parser, et à la proportion de chaque genre de déclaration rencontrée,
pour minimiser l'effort moyen de parsing en qque sort :)

si une grosse partie des déclarations que je lis étaient plus complexe que
la forme [const] nom-de-type [*|&], je changerais d'avis ! mais pour
l'instant cette forme représente facilement 95% de ce que je lis, alors je
me plais à lire les déclarations comme si la syntaxe était agréable, et
dans 5% des cas je lis une déclaration qui accroche un peu..

mais voir les 2 formes dans le même code ne me gêne pas vraiment en fait.


--
Sam

Avatar
kanze
Xavier Hardy wrote in message
news:...
"James Kanze" écrivait :
"Michaël Monerau" writes:
Pourquoi ça serait un cas particulier ?
Parce que ce ne suit pas la règle générale : que le const


modifie ce qui le précède.


Juste pour voir si je suis bien : selon cette convention
« rationnelle », il faudrait écrire "int const i = 1;"
au lieu de "const int i = 1;" et ainsi de suite ?


Selon cette convention, oui.

Cela fait vraiment bizarre quand on a jamais vu que l'autre écriture.


Tout fait bizarre la première fois qu'on le voit.

D'autant que si l'on voit "const" comme un qualificatif, le "const
int" a l'air assez naturel du point de vue de la langue anglaise.


Begin et end ont l'air assez naturel du point de vue de la langue
anglaise aussi, et quand je suis venu à C, du Pascal, les { et les }
m'avaient l'air bien bizarre. Maintenant, j'avoue que j'en ai
l'habitude, et qu'ils ne me choquent plus du tout.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16




Avatar
Alain Naigeon
"Gabriel Dos Reis" a écrit dans le message
news:
"Alain Naigeon" writes:

| Bof, ça fait partie de cette (fausse) humilité qu'on m'a

fausse ou non, cela fait partie de la pratique tout comme dire bonjour
à ses collègues le matin.

| inculquée dès le primaire, au point qu'il fallait se nommer
| "Naigeon Alain" lors des appels en classe, et non "Alain Naigeon" !

Jusqu'à nouveau désordre l'administration française place le nom avant
le(s) prénom(s).


Depuis quelque temps, j'ai décidé d'être autre chose qu'un point
dans un espace administratif ;-)


| Quand on a "l'orgueil" de dire quelque chose qu'on croit utile,
| on peut aussi avoir le courage de dire "moi", il me semble.

mais il n'est nullement interdit de dire « moi », la question portait
sur la place du moi ;-/


C'est à dire sur la nécessité qu'il s'efface derrière le moi de l'autre ?

--

Français *==> "Musique renaissance" <==* English
midi - facsimiles - ligatures - mensuration
http://anaigeon.free.fr | http://www.medieval.org/emfaq/anaigeon/
Alain Naigeon - - Strasbourg, France


-- Gaby


Avatar
Gabriel Dos Reis
"Alain Naigeon" writes:

| Depuis quelque temps, j'ai décidé d'être autre chose qu'un point
| dans un espace administratif ;-)

Joli !

| C'est à dire sur la nécessité qu'il s'efface derrière le moi de l'autre ?

sur la politesse de laisser passer le moi de l'autre ;-)

-- Gaby
Avatar
Xavier Hardy
"kanze" écrivait :
Juste pour voir si je suis bien : selon cette convention
« rationnelle », il faudrait écrire "int const i = 1;"
au lieu de "const int i = 1;" et ainsi de suite ?
Selon cette convention, oui.



Dans le même ordre d'idée, faudrait-il alors écrire
"int unsigned const i = 1;" ? Est-ce utile ?

Cela fait vraiment bizarre quand on a jamais vu que l'autre écriture.
Tout fait bizarre la première fois qu'on le voit.



Il y a quand même des choses qui paraissent plus naturelles
que d'autres même quand on les voit pour la première fois.
Désolé, pas d'exemple sous la main.

Begin et end ont l'air assez naturel du point de vue de la langue
anglaise aussi, et quand je suis venu à C, du Pascal, les { et les }
m'avaient l'air bien bizarre. Maintenant, j'avoue que j'en ai
l'habitude, et qu'ils ne me choquent plus du tout.


Certes, mais on s'habitue très vite à ne taper que deux caractères
au lieu de huit... Sauf avec ces satanés claviers français sur
lesquels il faut faire de la gymnastique pour avoir les accolades.

Xavier


Avatar
Xavier Hardy
"Samuel Krempp" écrivait :
de vue de la langue anglaise. Mais si on adopte la régle
que les déclarations peuvent généralement déchiffré en
les lisant de droite à gauche, la règle générale s'impose.
comme "unsigned int typedef size_t" ?

ça encore, on peut répondre que c'est particulier, typedef



En effet, pour ma part je fais une différence conceptuelle
entre les « déclarations/définitions » de type et celle
de variable.

Cela dit, je ne savais pas que la position du "typedef"
pouvait varier de place. Apparemment, on a aussi le droit d'aligner
autant de fois que l'on veut des "typedef"s identiques.

je penserais plutôt à des trucs comme

double (*f) (double);

qui est plus épineux pour qqun qui aime les choses simples.
(et c'est pour ça que Xavier a préciser généralement j'imagine)


Exactement.
Dans le C++ réformé de mes fantasmes, on écrirait ça ainsi :

double(double)* f;

De même pour les tableaux :

double[] da;

On abandonne donc la tradition du (et donc la compatibilité avec le)
C où la délaration singe l'usage. Ce qui permet de déclarer sans trop
se casser la tête un tableau de deux pointeurs constants sur des
fonctions qui prennent des doubles et renvoient des doubles :

double(double) * const [2] f_pt_a = { fptr1, fptr2 };

Je ne veux même pas essayer de savoir comment on peut faire ça
en C/C++...

Xavier



1 2 3 4 5