lundi 29 septembre 2014

Gcc prend ses aises

J'ai récemment ressorti OpenRailz de mes cartons, pour voir s'il compilait encore. Je lance donc comme d'hab ma commande omake -j 4. Et là, c'est le drame: en quelques minutes, ma machine est à genoux, swappe à n'en plus finir, le pointeur de souris devient saccadé... Je tue la compile, tout redevient normal. Je recommence, même punition mêmes motifs.

En y regardant de plus près, je me rends compte que chaque compilation mange à peu près 1Go de RAM. Avec 4 compilations en parallèle, c'est fini, mes 4 Go sont partis. Et tout ce qui a changé depuis la dernière fois où je compilais joyeusement cette solution, c'est la version du compilateur.

J'avais en effet entendu dire que particulièrement depuis gcc 4.8, la consommation mémoire s'était accrue, mais là, je l'ai senti en plein.

On vivra avec, parce que les fonctionnalités valent le coup. Mais moi qui me pensais à l'abri du besoin, me voilà lorgnant vers une petite mise à jour de ma RAM...

Coder efficacement avec Emacs - Sommaire et conclusion

Je remets ici la liste complète de mes tutoriels sur l'utilisation d'Emacs comme environnement de développement.

Je continue à être tout à fait satisfait de mon environnement Emacs, et sous Linux du moins, je ne me vois pas en changer. Il y a probablement moyen d'améliorer encore sa productivité, par exemple en utilisant les ctags pour faire de l'autocomplétion, mais celle-ci me semble peu utile tant qu'elle n'est pas contextuelle, et le bon vieux M-Esc / est bien plus simple pour un résultat presque aussi bon. Peut-être que la compétition renouvelée entre gcc et clang pourra nous donner de meilleurs outils d'autocomplétion ou de compilation à la volée qui s’intégreront avec Emacs. En attendant, je me contente très bien de ce que j'ai. Et le regard d'envie de mon vimeux de voisin lorsque je lance un gdb-many-windows n'a pas de prix :)

samedi 27 septembre 2014

Encore de la move semantics

J'avais déjà longuement parlé des coûteuses erreurs d'inattention liées à la move semantics lors du passage de paramètres, lorsque des objets qui paraissent parfaitement valides ne le sont plus. Je me suis fait avoir une fois de plus avant-hier. Ce n'est pas aussi terrible que la fois précédente, puisque mon test unitaire a très vite attrapé la faute, mais cela prouve qu'il est finalement assez difficile de ne pas se tromper.

J'ai donc commencé à implémenter l'idée initiale proposée par Yakk sur StackOverflow, et je nomme mes arguments abcMoved pour bien indiquer qu'il faut bien faire attention:

class Person
{
 public:
  A(std::string nameMoved, std::string addressMoved):
    _name(std::move(nameMoved)),
    _address(std::move(addressMoved)
  {
    std::cout << _name << " " << _address << std::endl;
  }

 private:
  std::string _name;
  std::string _address;
};

Avec cette manière de faire, un std::cout << nameMoved << std::endl devrait nous sauter au visage. J'essaie, et je vous en recause.

lundi 22 septembre 2014

Delegating constructors

Aujourd'hui, j'ai collé mon premier delegate constructor dans du code de production.

Jusqu'ici, je n'en avais pas vraiment ressenti le besoin: la grande majorité de mes classes n'a qu'un seul constructeur, et celles qui en ont plus ont généralement besoin de comportements très différents. Mais aujourd'hui, j'ai voulu utiliser un delegate constructor, pour rendre mon code plus facile à utiliser depuis les tests unitaires.

Dans mon cas, j'avais un constructeur qui prenait, entre autres, un gros objet, à partir duquel on retirait plusieurs petits pour les mettre dans des attributs. Le problème, c'est que ce gros objet est difficilement moquable, alors que les petits le sont facilement. De plus, je veux vraiment passer le gros objet (et pas les petits) par le constructeur, pour éviter que l'utilisateur ne s'emmêlle les pinceaux sur la manière d'extraire les petits.

Ma solution fut donc de créer un constructeur protégé qui prend les petits objets, appelé par mon constructeur principal public qui prend le gros. Pas de risques de mal utiliser la classe. Et depuis mes tests unitaires, je dérive mon objet, rend l'autre constructeur visible, et passe mes objets moqués.

C'est probablement un cas d'utilisation très particulier. Je ne pense pas avoir à réitérer l'expérience de si peu. Mais il est plaisant de trouver des cas d'utilisation qui rendent le code vraiment plus élégant.