Pages

samedi 23 mars 2013

Nouveau mode pour fopen

Depuis le temps que j’essayais de me rappeler ce nouveau mode. Je ne regardais juste pas la bonne doc. Mais le tir est corrigé, maintenant il est aussi là \o/.

Mais quelle est donc ce nouvel arrivant tout droit sorti du c11 ? Un simple inconnu, le mode "x" :D.
Ce nouveau mode (qui se met en dernier) permet quand il est avec le mode "w" de créer le fichier s'il n'existe pas et d'échouer dans le cas contraire.
Ça fonctionne comme les flags O_CREAT et O_EXCL de la fonction open.

Que de complexité, que de souffrance et que de temps perdu résumés en un simple "x"...

Par contre, je n'ai pas trouvé l'équivalent en C++ pour std::fstream.

dimanche 17 mars 2013

Ne pas empêcher la NRVO

La NRVO et la RVO sont des optimisations des compilateurs pour retourner un objet sans le copier. Je renvoie directement sur une partie de la FAQ C++ de développez.com: d'ici jusqu'à la fin.

Cependant ces optimisations ne s'appliquent pas lorsqu'un appel de méthode qui retourne son instance est directement retourné (une référence sur elle-même).
Ceci:

S f()
{
  S ret;
  return ret.action(); //S& action() { /*...*/ return *this; }
}

Ou cela:

iterator operator+(const iterator& other, int n)
{ return iterator(other) += n; }

Dans ces 2 exemples l'objet est copié inutilement. Pour éviter cette copie, il faut décomposer le code pour que le retour de la fonction ne soit pas lié à une méthode: il faut retourner explicitement l'objet. Ainsi la variable de retour est une variable nommée et la NRVO s'applique.

S f()
{
  S ret;
  ret.action();
  return ret;
}

Et cela:

iterator operator+(const iterator& other, int n)
{
  iterator ret(other);
  ret += n;
  return ret;
}

C'est une optimisation facile à faire et il est tout aussi facile de passer à côté ;).

samedi 9 mars 2013

Petite curiosité de volatile

Voici une petite curiosité du mot clef volatile.

#include <iostream>

struct S{};

void f(void*) { std::cout << 'p'; }
void f(bool) { std::cout << 'b'; }

int main()
{
    S s;
    volatile S * p1 = &s;
    S * p2 = &s;
    f(p1);
    f(p2);
}

Résultat: bp

Le pointeur volatile passe dans la fonction demandant un booléen. Ce n'aurait pas été le cas si un prototype avec volatile void * ou templater sur un _T* existait.

lundi 4 mars 2013

Sqlite, reconstruire la bdd pour l'alléger.

Je ne vais pas par 4 chemins : VACUUM.

Cette commande permet de reconstruire une table et ainsi éliminer les lignes vides et réorganise les index (c'est mieux dit dans la doc ^^).
Certains logiciels se servent de sqlite ; utiliser cette commande de temps en temps sur les tables est une bonne idée.
La première fois que je l'ai fait pour firefox (fichier ~/.mozilla/firefox/nom-du-profil/*.sqlite sur linux) j'ai gagné ½ giga :).

Voici un petit script qui va permettre de le faire sur tous les fichiers sqlite du système (du moins, ceux indexés) et connaître la taille totale avant et après utilisation:

#!/bin/sh
tmpf=/tmp/sqlite_file_path
locate \.sqlite \
| xargs -d'\n' mimetype \
| grep 'application/x-sqlite3$' \
| sed 's/:\s*application\/x-sqlite3\s*$//' \
> $tmpf
xargs --arg-file $tmpf -d'\n' du -hc | tail -n1
while read f ; do
 sqlite3 "$f" 'VACUUM;'
 [ $? -ne 0 ] && echo "\tfor $f"
done < $tmpf
xargs --arg-file $tmpf -d'\n' du -hc | tail -n1
rm $tmpf

Une petite version pour cibler les fichiers:

#!/bin/sh
for f in "$@" ; do sqlite3 "$f" 'VACUUM;'; done