dimanche 3 août 2014

Passage de paramètres et move semantics - Planté!

J'avais posé la question sur StackOverflow, et je n'avais pas vraiment obtenu d'autre réponse que "il faut faire attention": avec la nouvelle manière de passer les paramètres qui seront copiés, en les passant par valeur puis en les déplaçant localement, il existait un grand risque d'utiliser par erreur le paramètre après son déplacement. Et c'est ce qui m'est arrivé il y a quelques jours, me coutant 2 bonnes heures de boulot. Je vous le fait en simplifié:

class A()
{
public:
  A(std::string instance):
    _instance(std::move(instance)),
    _logPrefix("Class A : " + instance)
  {
  }

private:
  std::string _instance;
  std::string _logPrefix;
}

Avec l'ancienne convention, instance aurait été passé comme une référence constante. Avec la nouvelle, l'on déplace instance dans _instance, mais après, il ne faut surtout pas l'utiliser! Une petite erreur d'inattention, et mon _logPrefix contient n'importe quoi, ce qui cassait tout. En l’occurrence, il contenait "Class A: ", mais cela aurait tout aussi bien pu être un beau crash.

Dommage. Je finis par me demander s'il ne faut pas garder l'ancienne convention, et n'utiliser la nouvelle que dans du code qui a vraiment besoin des performances et qui a une chance de se retrouver avec une l-value dans le paramètre.

Aucun commentaire: