4 votes

"Le contrôle atteint la fin sur une fonction non vide" avec do { return result ; } while(condition) ;

J'ai la fonction suivante (exemple réduit) :

QByteArray DecompressBytes(const QByteArray& content){
  /* function body (with other return expressions) */

  do { return content; } while(content.size() != 0);
}

La dernière ligne a été ajoutée pour les tests, en remplacement d'une macro utilisée. Visual Studio ne voit pas de problème avec ce code, mais g++ génère

avertissement : la commande atteint la fin d'une fonction non vide [-Wreturn-type].

Changer la dernière ligne en return content; supprime l'avertissement.
Ma question : pourquoi le compilateur se comporte-t-il ainsi et quelle devrait être la forme du code pour éviter tout avertissement ?

La dernière ligne était auparavant ASSERT_FAIL("must be unreachable", content) con ASSERT_FAIL en s'étendant sur do { ... } while(false) avec une autre macro remplaçant while pour interdire les expressions non-bool, donc l'expression résultante était comme do { qt_assert_x("", "", 42); return content; } while(::helper::bool_verify(false)); .

g++ version 5.3.0, utilisé avec MinGW (configuration Qt standard).

Mise à jour : après avoir essayé de commenter différentes parties du code (puisque l'exemple pur ci-dessus ne permet pas de reproduire le problème), quelque chose de vraiment étrange est apparu :

QByteArray DecompressBytes(const QByteArray& content){
  QByteArray decompressed; //no 'unused variable' warning
  do { return content; } while(content.size() != 0);
} //produces warning above

QByteArray DecompressBytes2(const QByteArray& content){
  //QByteArray decompressed;
  do { return content; } while(content.size() != 0);
} //doesn't produce warning

std::vector<char> DecompressBytes3(const std::vector<char>& content){
  std::vector<char> decompressed; //no 'unused variable' warning

  do { return content; } while(content.size() != 0);
} //does produce warning

std::vector<char> DecompressBytes4(const std::vector<char>& content){
  int decompressed; //unused variable warning is given

  do { return content; } while(content.size() != 0);
} //doesn't produce warning

Je ne suis pas sûr de ce que tout cela signifie.

4voto

gsamaras Points 9567

C'est étrange. GCC 4.9.2 avec le drapeau Wall ne se plaint pas de ce code similaire (je n'ai pas installé qt).

#include <vector>

std::vector<int> foo(const std::vector<int>& v)
{
    do { return v; } while( v.size() != 0 );
}

int main() {std::vector<int> v; foo(v);}

Idem avec clang 4.2.1. En conséquence, je dirais que c'est quelque chose de spécifique à votre installation, et si j'étais vous, j'ajouterais une déclaration de retour factice à la fin de la fonction, ou j'utiliserais un drapeau pour me débarrasser de cet avertissement.


Mise à jour : J'ai reproduit le comportement des deux dernières nouvelles fonctions fournies par l'OP avec GCC, alors que clang a soulevé un problème de 'variable inutilisée' uniquement pour les fonctions suivantes DecompressBytes4() .

Une explication possible est que cette pendant ce temps que vous avez là n'est pas vraiment utilisé dans la pratique. L'élimination du code mort se produit, ne laissant que l'instruction de retour.

Cependant, lorsque nous utilisons une variable supplémentaire, le mécanisme d'élimination du code mort ne fonctionne pas de la même manière, certaines informations sont préservées et il ne voit pas l'instruction de retour.

Habituellement, l'élimination du code mort se fait en back-end, tandis que les avertissements sont émis par le front-end. Dans ce cas, il semble que ces deux-là ne communiquent pas brillamment ! =)


PS - Élimination des codes morts explique pourquoi vous n'avez pas non plus d'avertissement d'inaccessibilité.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X