OVH Cloud OVH Cloud

warning: control may reach end of non-void function 'T&

5 réponses
Avatar
meow
Hello,

J'ai un truc du genre :

T& operator()(int i,int j,int k) const {
switch (s) {
case 0 : return g->get(i,j,k);
case 1 : return g->get(k,i,j);
case 2 : return g->get(j,k,i);
}
}

Comment puis-je faire pour dire au compilo que sur ce coup l=E0 je
sais ce que je fais... En l'occurence 's' ne peut avoir d'autre valeur
que 0,1 ou 2.
Comme la valeur de retour est une r=E9f=E9rence je ne vois pas comment la
stocker dans un temporaire. Pour le moment j'ai fait un truc pas beau :
juste ajout=E9 un return g->get(0,0,0) avant l'accolade finale. Du code
mort pour que le compilo ait l'impression que =E7a se passe bien : beurk
non ?

5 réponses

Avatar
Fabien LE LEZ
On 12 Jun 2006 09:14:08 -0700, "meow" :

Comment puis-je faire pour dire au compilo que sur ce coup là je
sais ce que je fais... En l'occurence 's' ne peut avoir d'autre valeur
que 0,1 ou 2.


Deux solutions :
- Si tu veux dire au compilateur de supprimer un warning, il y a
certainement un #pragma (spécifique à ton compilo) qui permet de le
faire.
- Sinon, quitte à rajouter du code mort à la fin, lance plutôt
une exception que renvoyer une valeur incorrecte :

T& operator()(int i,int j,int k) const
{
switch (s) {
case 0 : return g->get(i,j,k);
case 1 : return g->get(k,i,j);
case 2 : return g->get(j,k,i);
}
throw std::out_of_range ("valeur de s incorrecte");
}

Avatar
Olivier Miakinen
Le 12/06/2006 18:21, Fabien LE LEZ répondait à meow :

- Sinon, quitte à rajouter du code mort à la fin, lance plutôt
une exception que renvoyer une valeur incorrecte :

T& operator()(int i,int j,int k) const
{
switch (s) {
case 0 : return g->get(i,j,k);
case 1 : return g->get(k,i,j);
case 2 : return g->get(j,k,i);
}
throw std::out_of_range ("valeur de s incorrecte");
}


Une autre possibilité, si tu es absolument sûr que seules ces trois
valeurs sont possibles, c'est :

T& operator()(int i,int j,int k) const {
switch (s) {
case 0 :
return g->get(i,j,k);
case 1 :
return g->get(k,i,j);
default /* i.e. 2 */ :
return g->get(j,k,i);
}
}



--
Olivier Miakinen
Troll du plus sage chez les conviviaux : le nouveau venu, avec
son clan, s'infiltre dans les groupes de nouvelles. (3 c.)

Avatar
fabien.chene
"meow" writes:

J'ai un truc du genre :

T& operator()(int i,int j,int k) const {
switch (s) {
case 0 : return g->get(i,j,k);
case 1 : return g->get(k,i,j);
case 2 : return g->get(j,k,i);
}
}

Comment puis-je faire pour dire au compilo que sur ce coup là je
sais ce que je fais... En l'occurence 's' ne peut avoir d'autre valeur
que 0,1 ou 2.


Quel est le type de s ?
Si s ne peut prendre que les valeurs 0, 1, ou 2, ce n'est peut être
pas idiot que son type soit un type énuméré.


--
Fab

Avatar
meow
default
Oui, bonne idée


Quel est le type de s ?
Si s ne peut prendre que les valeurs 0, 1, ou 2, ce n'est peut être
pas idiot que son type soit un type énuméré.


C'est aussi ce que je me suis dit... mais en meme temps un type pareil,
je me sens obligé de l'encapsuler dans ma classe. Du coup je devrai me
fader des arguments à ralonge du genre :
TriangularGrid::Accessor::Iside

merci pour vos suggestions

Avatar
kanze
meow wrote:

J'ai un truc du genre :

T& operator()(int i,int j,int k) const {
switch (s) {
case 0 : return g->get(i,j,k);
case 1 : return g->get(k,i,j);
case 2 : return g->get(j,k,i);
}
}

Comment puis-je faire pour dire au compilo que sur ce coup
là je sais ce que je fais... En l'occurence 's' ne peut avoir
d'autre valeur que 0,1 ou 2.


Ça n'existe pas en C++. Ce que tu veux dire, sans doute, c'est
que s'il n'y a pas d'erreur dans le code ailleurs, s ne peut
prendre que ces trois valeurs. Mais c'est un grand si, et en
général, dans de tels cas, il est usuel d'ajouter un cas
default :

default : assert( 0 ) ; abort() ;

Comme la valeur de retour est une référence je ne vois pas
comment la stocker dans un temporaire.


T* result ;
// ...
result = &g->get(i,j,k) ;
// ...
return *result ;

Mais ce n'est pas particulièrement beau.

Pour le cas précis ici, on pourrait aussi se servir des
opérateurs ?: :

T& operator()( int i, int j, int k ) const
{
return s == 0
? g->get(i,j,k)
: s == 1
? g->get(k,i,j)
: s == 2
? g->get(j,k,i)
: throw "C'est foutu" ;
}

Mais ça ne s'étend pas : trois valeurs, c'est vraiment la
limite. Et les règles de typage font qu'on soit obligé à
utiliser un throw en cas d'erreur, bien que assert/abort
convient beaucoup mieux.

Pour le moment j'ai fait un truc pas beau :
juste ajouté un return g->get(0,0,0) avant l'accolade finale.


Encore plus simple : ignorer l'avertissement. (Dans le code de
production, c'est assez simple d'ajouter un filtre après le
compilateur, de façon à ce que les avertissements sans intérêt
n'apparaissent même pas dans le log -- et n'empêche pas que le
check-in marche.)

--
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