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

3 4 5 6 7
Avatar
kanze
Gabriel Dos Reis wrote:
Fabien LE LEZ writes:

je ne comprends pas pourquoi tu devrais croire que c'est
une multiplication par deux -- de fait tu as dejà fait une
hypothèse sur le type de « x ».


Mon hypothèse de travail est qu'il n'y a pas d'abus de
surcharge, et


pour moi « abus de surcharge » avant même d'avoir explorer le
domaine d'utilisation et les alternatives est un non-argument
: c'est du fanatisme.


Est-ce que je peux rappelé ici que le type en question est int ?
Il n'y a pas de surcharge, au moins pas défini par
l'utilisateur. Et que la question posée, c'est quand on veut
multiplier par 2, est-ce qu'il faut écrire « 2 * x » (comme
prétend Fabien et moi), ou « x << 1 » (que certains ont prétendu
meilleur).

Il s'agit de la lisibilité du code dans l'absence même de tout
surcharge.

qu'un operator* (à deux arguments) signifie bien quelque
chose qui ressemble fort à une multiplication.

Je présume que ce que je veux dire, c'est que tout est
question de contexte.


En partie seulement. Si je vois un "++", je sais qu'il
s'agit soit d'une addition (type numérique), soit d'un
passage à l'élément suivant (itérateur). Si "++" sert à
multiplier par 3, je vais finir par le


Si « multiplier par 3 » est *l'implémentation* de passer à
l'élement suivant, alors on est bon pour la guillotine aussi ?


Pourquoi est-ce que tu veux toujours être de mauvaise fois ?
C'est clair que Fabien ne parlait pas de l'implémentation, mais
de la sémantique visée du point de vue de l'utilisateur.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34



Avatar
kanze
Marc Boyer wrote:

[...]
Ou plus prêt de mon point de vue d'enseignant, qu'un
débutant ayant suivit un cours de C++ peut ne pas avoir
vu << comme opérateur de décalage binaire, et que c'est
peut-être plus rare pour du C.


J'ai déjà eu l'occasion de travailler avec un programmeur C qui
ne l'avaient jamais vu. Maîtrise en informatique de l'université
de York, en Angleterre.

Le problème, c'est qu'on ne peut jamais avoir tout vu. Alors, la
question, c'est qu'est-ce qu'il y a de plus important. Si le but
est d'être expert en C++, il faut l'avoir vu. Si le but est
d'être expert en informatique bancaire, par exemple, ça me
semble moins évident -- le temps serait mieux passé à apprendre
la SQL, par exemple.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Avatar
kanze
Gabriel Dos Reis wrote:
Fabien LE LEZ writes:

On 06 Mar 2006 16:38:59 +0100, Gabriel Dos Reis
:

Que les développeur C++ sont plus habitués à penser
sémantique avant de penser optimisation ?


comme le montre la bibliothèque standard de C++ ?


La SL est à mi-chemin entre le compilateur et un programme
"normal" : elle doit être optimisée pour que justement le
programmeur n'ait pas à se préoccuper d'optimisation.


je parle de l'initerface utilisateur -- pas de son
implémentation. L'optimisation a pris le dessus sur la
sémantique.


Pas toujours. Passer tous ces objets, potentiellement complexes,
par valeur, ce n'est pas « l'optimisation ». Ou dans un cas qui
m'a touché directement : utiliser l'opérateur +, et non
l'opérateur +=, dans std::accumulate, n'est pas ce que
j'appelerais une optimisation. (Dans mon cas,
l'« accumulateur », c'est un accumulateur du hachage MD-5. Avec
un sizeof de 80 octets.)

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34




Avatar
Laurent Deniau
Sylvain wrote:
Marc Boyer wrote on 06/03/2006 18:08:


Et tu remarqueras que le C++,
contrairement au C, a spécifiquement introduit un mot clé -- « asm »).


Je ne l'avais pas noté.



selon K&R, il était réservé (/réservé/ uniquement) par certaines
implémentations (de même que "fortran").

Je reviens quand même sur le contexte de cette discussion qui
était de la fonction int Double([const] int x); qui retourne
le double de x *devrait* se coder
return x<<1;



j'ai bien dit "devrait" (should) et non "doit" (shall).

cette remarque ne pouvait avoir de sens que dans un contexte un peu plus
précis, or ce n'était pas l'objet initial; de plus l'extrait (d'un post
annulé mais pas assez vite) ne reprenait que ce point alors que
l'élément discuté concernait "int Rapport(const int a,const int b)" qui
ne compilait pas.

profitant de votre fil posé et constructif, je préciserai que la réponse
"devrait" était un raccourci à "une telle fonction ne 'doit' jamais
exister" mais l'opération doit être inlinée (sinon le cout d'appel est
prohibitif par rapport au traitement) et ce codage selon l'opérande et
la famille de compilos visés pourra être "optimisé d'office" par un
shift si cela semble opportun.

or donc, la question concernait l'usage du modifier 'const' et non le
bien fondé d'une telle fonction, j'ai donc opté pour la version courte,
un peu pour voir ... et j'ai vu.


pour répondre à la remarque de l'autre post:

A tout prendre, je prefererais qu'il sache qu'un decalage
a droite c'est une *division* par deux sur un entier non
signe et que c'est dependant de l'implementation sur
un entier signe.


Oui ;-)


il a été rappellé que les opérateurs de décalage sont contextuels (ils
ne sont pas un codage fixe en asm);


Les operateurs de *decalage* (shift operators) ne sont pas contextuel.
Il s'applique a un entier ou a un enum.

pour un décalage à droite, si le
type entier est signé, le compilo doit générer un décalage signé
(restauration du bit de signe, soit SAR sur Intel) tandis qu'un opérande


non, c'est dependant de l'implementation, comme je l'ai dit. Un decalage
a droite sur un type signe est donc a eviter que ce soit en C ou en C++.

non signé subira un décalage non signé (injection de 0 à gauche, SHR sur
Intel).


oui.

a+, ld.



Avatar
kanze
Marc Boyer wrote:

Très certainement, nous attendons de l'étudiant « electrical
engineer » ou « computer engineer » qui prend le cours de
C++ 101 de savoir ce qu'est le décalage binaire et comment
cela s'écrit en C++.


C'est vrai ?
Et dire que mes étudiants me trouvent exigeants...


La question, c'est qu'est-ce qu'ils n'ont pas vu à la place ?

Beaucoup dépend du but du cour, et le temps alloué. En ce qui
concerne les « electrical engineers », par exemple, je trouve
qu'un présentation des problèmes inhérants dans le calcul
numérique avec float et double beaucoup plus important que les
décalages. Mais si le temps alloués suffit pour qu'ils puissent
apprendre les deux...

Qu'un informaticien sache ce qu'est un décalage, c'est une
exigence que je partage.


C'est ce que je croyais il y a vingt ans aussi. Je le trouve
toujours une bonne idée, mais j'ai aussi travaillé avec un
ingenieur extrèmement compétant qui ne l'avait pas appris.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Marc Boyer
Le 06-03-2006, Sylvain a écrit :
Je reviens quand même sur le contexte de cette discussion qui
était de la fonction int Double([const] int x); qui retourne
le double de x *devrait* se coder
return x<<1;


j'ai bien dit "devrait" (should) et non "doit" (shall).

cette remarque ne pouvait avoir de sens que dans un contexte un peu plus
précis,


Qui n'était pas donné.

profitant de votre fil posé et constructif, je préciserai que la réponse
"devrait" était un raccourci à "une telle fonction ne 'doit' jamais
exister" mais l'opération doit être inlinée (sinon le cout d'appel est
prohibitif par rapport au traitement) et ce codage selon l'opérande et
la famille de compilos visés pourra être "optimisé d'office" par un
shift si cela semble opportun.


C'est parce que le "si cela semble opportun" n'était pas
explicité que j'avais demandé si vous en étiez sur.

Entre autre, en complément à 1, (-1)<<1 != -2.

Que le complément à 1 soit rarissime, je peux en convenir.

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
Gabriel Dos Reis
"kanze" writes:

| Gabriel Dos Reis wrote:
| > Fabien LE LEZ writes:
|
| > > > je ne comprends pas pourquoi tu devrais croire que c'est
| > > >une multiplication par deux -- de fait tu as dejà fait une
| > > >hypothèse sur le type de « x ».
|
| > > Mon hypothèse de travail est qu'il n'y a pas d'abus de
| > > surcharge, et
|
| > pour moi « abus de surcharge » avant même d'avoir explorer le
| > domaine d'utilisation et les alternatives est un non-argument
| > : c'est du fanatisme.
|
| Est-ce que je peux rappelé ici que le type en question est int ?

rappelle tout ce que tu veux, à défaut d'avoir lu ce à quoi je
répondais (cela fera pour toi, comme d'hab, une occasion de parler
sans rien dire), qui est :

En C++, la situation est différente : d'une part, en voyant un "<<",
on pense immédiatement aux iostream ; d'autre part, il me semble qu'en
C++ on a un réflexe "généricité" : *si je dois multiplier x par 2,
j'écris x*2 sans me préoccuper de savoir de quel type est x
(D'ailleurs, je ne le sais pas forcément)* ; c'est au compilateur de

[...]

| > > >Je présume que ce que je veux dire, c'est que tout est
| > > >question de contexte.
|
| > > En partie seulement. Si je vois un "++", je sais qu'il
| > > s'agit soit d'une addition (type numérique), soit d'un
| > > passage à l'élément suivant (itérateur). Si "++" sert à
| > > multiplier par 3, je vais finir par le
|
| > Si « multiplier par 3 » est *l'implémentation* de passer à
| > l'élement suivant, alors on est bon pour la guillotine aussi ?
|
| Pourquoi est-ce que tu veux toujours être de mauvaise fois ?

Bof, quand t'es pris en flagrant délit il faut que tu fasses une
diversion. Ça marche pas tout le temps, James. Trouve autre chose ou
alors fais profile bas.

| C'est clair que Fabien ne parlait pas de l'implémentation, mais
| de la sémantique visée du point de vue de l'utilisateur.

Bah non ; d'ailleurs dans les tentatives d'éclaircissement plus tard,
Fabien n'a pas réussi à montrer la distinction. Voir son exemple
Entier et ma réponse MyIter.

-- Gaby
Avatar
Gabriel Dos Reis
"kanze" writes:

[...]

| > et les programmeurs C++ que je connais (et que respecte
| > profondément) lisent « << » dans le contexte.
|
| Je crois que la clé, c'est que ce sont des programmeurs C++ ;
| c-à-d plus ou moins spécialisé dans le C++. Il faut dire que la
| majeur partie des programmeurs que je vois, ce sont des
| programmeurs dans la bancaire, ou des programmeurs dans les
| télécoms -- leur intérêt principal se situe à un autre niveau ;
| pour eux, le C++ n'est qu'un outil (parmi d'autres), et leur
| connaissances du langage proprement dit se bornent à ce qu'il

Je parlais avant tout de *programmeurs* C++ que j'ai vus. À
l'évidence, nous ne naviguons pas dans le même monde ; mais je me
garderai de dire que ce que je n'ai pas vu n'existe pas.

| leur faut pour faire leur travail. (En général, si j'y suis,
| c'est que la direction reconnaît qu'il faut de tout, et qu'il
| faut au moins une personne avec une connaissance approfondie du
| langage auxquels les autres peuvent s'adresser, le cas échéant.)
|
| Dans les domaines où je travaille, très souvent, la seule
| utilisation de <<, c'est pour les logs, et >> n'apparaît jamais.

oui, tu es Programmeur C++ et ce que tu ne vois pas n'existe
pas.

[...]

| (En fait, le paragraphe ci-dessus doit être compris comme une
| question. Je crois qu'il correspond à ce que tu dis, mais je ne
| suis pas sûr.)
|
| J'irais plus loin... Il y a entier et entier, et si je ne
| m'intéresse qu'à la valeur numérique, et non à sa
| représentation, ou des bits qui la soutendent, je ne m'attends
| pas à un opérateur <<.
|
| > En géneral « x << y » fait ce que « << » est défini dans le
| > contexte de « x » et « y ».
|
| C'est vrai pour n'importe quel opérateur C++, non ?

Vraiment ? Cela n'apparaît pas évident dans cette sous-discussion
avec Fabien.

| C'est
| seulement par convention qu'on s'attend à ce qu'un surcharge ait
| une sémantique en quelque sort « apparentée » à la sémantique
| sur les types de base.

Définis '« apparentée »' -- puisque tu l'as mis entre guillements, je
suppose que tu ne voulais pas utiliser la signification ordinaire.

[...]

| > La généricité, justement d'avoir du code « symbolique », dont
| > les interprétations dans différents contextes donnent les
| > algorithmes initiaux et que le tout reste compréhensible dans
| > le contexte d'utilisation.
|
| > > c'est justement j'écris x*2 sans me préoccuper de savoir de
| > > quel type est x
|
| > si on ne doit pas se préoccuper de quel type est x et qu'on
| > écrit « x << 2 », je ne comprends pas pourquoi tu devrais
| > croire que c'est une multiplication par deux -- de fait tu as
| > dejà fait une hypothèse sur le type de « x ».
|
| La contexte ici,

est ce à quoi je répondais là : le texte est encore sous tes yeux.

| à laquelle Fabien répond, c'est que quelqu'un a
| prétendu qu'écrire « x << 1 », quand on veut multiplier par
| deux, c'est la signe d'un bon programmeur.

Relis la généralisation qu'il a faite.

[...]

| Il y a une ontologie professionnelle, que tu le veuilles ou non.

mais oui, monsieur.

-- Gaby
Avatar
Gabriel Dos Reis
"kanze" writes:

| Gabriel Dos Reis wrote:
| > Fabien LE LEZ writes:
|
| > > On 06 Mar 2006 16:38:59 +0100, Gabriel Dos Reis
| > > :
|
| > > >> Que les développeur C++ sont plus habitués à penser
| > > >> sémantique avant de penser optimisation ?
|
| > > >comme le montre la bibliothèque standard de C++ ?
|
| > > La SL est à mi-chemin entre le compilateur et un programme
| > > "normal" : elle doit être optimisée pour que justement le
| > > programmeur n'ait pas à se préoccuper d'optimisation.
|
| > je parle de l'initerface utilisateur -- pas de son
| > implémentation. L'optimisation a pris le dessus sur la
| > sémantique.
|
| Pas toujours. Passer tous ces objets, potentiellement complexes,
| par valeur, ce n'est pas « l'optimisation ».

Je tiens des personnes impliquées dans cette histoire qu'elles ont
préféré passage par valeur à passage par référence pour des raisons
d'efficacité et que ces objets, dans la majorité des cas
d'utilisation, ne sont pas supposés être « complexes. »

-- Gaby
Avatar
Jean-Baptiste Bavoux
Sylvain wrote:
Marc Boyer wrote on 03/03/2006 12:24:

devrait lire return 2.0 * x;


Et pourquoi ce passage en double ?


j'ai été abusé par le "Double" (nom de fonction) que j'ai lu
comme "double" (type retour), dans un tel cas il fait sens de
forcer une multiplication flottante ; j'ai annulé mon post
après avoir relu.


C'est vrai que le nom n'est pas superbe. (Mais
réalistiquement... je crois que l'intention n'était que d'avoir
un exemple simple, et non de donner du code de production. Je
doute fort que dans un vrai projet, on aurait jamais une telle
fonction.)



Effectivement c'etait uniquement pour l'exemple.
Je cherchais une methode la plus simple possible ( quoi de plus simple
que de multiplier par 2).
En plus j'aurais du me rendre compte que cela pretait a confusion car
j'ai du l'appeller Double avec un majuscule pour compiler.

Ca aurait été plus clair avec:
int Triple(const int x)
{
return 3 * x;
}




3 4 5 6 7