Cplusplus11, découverte de ce nouveau dialecte

Il y a quelques mois je me réjouissais de la validation du standard C++11. Je regrette toujours que les sockets réseau n’aient pas été implémenté.

Après plusieurs lectures sur le sujet, je recherche l’adoption totale de la nouvelle syntaxe de C++11. Tentons de dompter les nouveautés. Les exemples sont testés avec GCC version 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3), le code source est disponible sur GitHub.

Nous allons commencer à travailler sur les types automatiques avec le mot clé auto et l’opérateur decltype.

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>//for_each
#include<typeinfo>//typeid

int main() {
  std::vector<std::string> data{"first", "second", "third"};//uniform brace notation
  for (const auto item : data) {//Range based for loop
  std::cout << "Iterate =>" << std::endl;
    std::cout << "  Automatic item type: " << typeid(item).name() << " - Item value: " << item << std::endl;
    decltype(item) dynamic_value = item;
    std::cout << "  Dynamic type: " << typeid(dynamic_value).name() << " - Dynamic value: " << dynamic_value << std::endl;
    std::cout << std::endl;
  }
  return 0;
}

Dans cet exemple nous initialisons un vecteur de chaîne de caractères puis bouclons sur chaque item ; le type de chaque item est récupéré automatiquement et nous créons dynamiquement une variable du même type que l’item. Pour le moment ne tenez pas compte de la syntaxe particulière de la boucle for.

Simplification de l’itération simple d’un conteneur avec la structure de contrôle for.

#include<iostream>
#include<vector>
#include<string>

int main() {
  std::vector<std::string> data{"first", "second", "third"};
  for(const auto item : data) {
    std::cout << "Item value: " << item << std::endl;
  }
  return 0;
}

Une simple boucle for tel que le propose déjà des langages tel que Java ou C#. Un vrai bonheur pour notre langage. Notons que pour un parcours spécifique ou plus complexe, il est plus puissant d’utiliser for_each ; par exemple commencer l’itération à partir du 3ème élément.

Avant C++11, la macro NULL équivalente à 0, est parfois considéré comme très particulière par les développeurs et porte à confusion. C++11 propose une expression nullptr, plus d’excuses et arrêtons d’utiliser 0 ou NULL pour initialiser un pointeur.

#include<iostream>
#include<vector>

int main() {
  const int* p = nullptr;
  std::vector<int> data{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
  for (const auto item : data) {
    p = &item;
    std::cout << "Item pointer: " << *p << std::endl;
  }
  return 0;
}

On initialise un pointeur avec nullptr et non 0, puis on boucle sur les données en assignant l’adresse de chaque item au pointeur p.

Uniformisation de l’initialisation avec les accolades {}. Avant C++11, selon qu’on veut initialiser un tableau, les membres d’une structures… avec des zéros ou avec des valeurs différentes de zéro, il fallait passer par des syntaxes différentes. Avec C++11 on arrête avec toutes ces possibilités, on uni formalise comme le montre le code source suivant :

#include<string>
#include<sstream>
#include<vector>

struct Version {
  uint32_t major;
  uint32_t minor;
  uint32_t revision;

  std::string toString() const {
    std::ostringstream oss;
    oss << major << "." << minor << "." << revision;
    return oss.str();
  }
};

int main() {
  Version v{0, 1, 0};//Constructor initialization
  std::cout << "Version v{0, 1, 0}: " << std::endl;
  std::cout << "  " << v.toString() << std::endl;
  std::vector<Version> vArray{{0, 1, 0}, {0, 1, 1}, {0, 1, 2}};//Array initialization
  std::cout << "std::vector<Version> vArray{{0, 1, 0}, {0, 1, 1}, {0, 1, 2}}: " << std::endl;
  for (const auto v : vArray) {
    std::cout << "  " << v.toString() << std::endl;
  }
  return 0;
}

On crée une instance de Version en initialisant major, minor et revision. On crée ensuite un vecteur de Version en initialisant les 3 premiers éléments.

Les nombres aléatoires, peuvent être générés selon un nouveau modèle qui se compose de deux éléments, un moteur de génération de nombre (il y en a plusieurs au choix) et une distribution soit une plage de nombre pouvant être généré, là encore on a le choix de la distribution ; voir un aperçu via ce lien.

#include<iostream>
#include<random>//std::mt19937, std::uniform_int_distribution
#include<functional>//std::bind
#include<ctime>

std::mt19937 engine;
std::uniform_int_distribution<uint32_t> distribution{1, 10};

int main() {
  engine.seed(static_cast<uint32_t>(std::time(nullptr)));
  auto generator = std::bind(distribution, engine);
  uint32_t random = generator();
  std::cout << "1st random: " << random << std::endl;
  random = generator();
  std::cout << "2nd random: " << random << std::endl;
  return 0;
}

Dans cet exemple on instancie le moteur de génération de type Mersenne Twister avec une distribution uniforme d’entier. On initialise dans la méthode main, le moteur avec un nombre entier récupérer de l’horloge de la machine. On se fabrique une fonction generator qui permet d’appeler notre générateur avec un nom plus intuitif.

Voilà c’est une première mise en jambe avec C++11 histoire de s’échauffer. Je reste persuadé du potentiel de ce langage et de son avenir glorieux. C++11 est le langage le plus concis et rapide de la planète.

Mise à jour officielle Google Nexus ICS 4.0.2 vers ICS 4.0.4 IMM76I (Ubuntu 11.10)

J’ai acheté il y a 4 mois le smartphone Google Nexus chez Rue du Commerce, mais depuis, et je ne sais pas pourquoi, à chaque annonce de mise à jour d’Android Ice Cream Sandwich, impossible que la détection des mises à jour me propose quoique ce soit…

Finalement ce matin j’ai décidé de réaliser manuellement cette mise à jour via les outils et fichiers officiels de Google (Pas besoin de rooter le téléphone).

La première chose à faire est d’installer le SDK Android via le lien suivant (pour les connaisseurs, uniquement le binaire fastboot est suffisant) : http://developer.android.com/sdk/installing.html.

Vérifier la configuration USB du Google Nexus sur la machine en vérifiant ou créant le fichier des droits udev (seules les lignes des Google Nexus sont nécessaires mais qui sait, j’aurai peut-être le bonheur de tester d’autres Google Android devices)

chris@tux:~/tmp/yakju-imm76i$ sudo emacs /etc/udev/rules.d/51-android.rules

Copier/coller les lignes suivantes dans le fichier /etc/udev/rules.d/51-android.rules

# adb protocol on passion (Nexus One)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e12", MODE="0600", OWNER="##votre_nom_d_utilisateur##"
# fastboot protocol on passion (Nexus One)
SUBSYSTEM=="usb", ATTR{idVendor}=="0bb4", ATTR{idProduct}=="0fff", MODE="0600", OWNER="##votre_nom_d_utilisateur##"
# adb protocol on crespo/crespo4g (Nexus S)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e22", MODE="0600", OWNER="##votre_nom_d_utilisateur##"
# fastboot protocol on crespo/crespo4g (Nexus S)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e20", MODE="0600", OWNER="##votre_nom_d_utilisateur##"
# adb protocol on stingray/wingray (Xoom)
SUBSYSTEM=="usb", ATTR{idVendor}=="22b8", ATTR{idProduct}=="70a9", MODE="0600", OWNER="##votre_nom_d_utilisateur##"
# fastboot protocol on stingray/wingray (Xoom)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="708c", MODE="0600", OWNER="##votre_nom_d_utilisateur##"
# adb protocol on maguro/toro (Galaxy Nexus)
SUBSYSTEM=="usb", ATTR{idVendor}=="04e8", ATTR{idProduct}=="6860", MODE="0600", OWNER="##votre_nom_d_utilisateur##"
# fastboot protocol on maguro/toro (Galaxy Nexus)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e30", MODE="0600", OWNER="##votre_nom_d_utilisateur##"
# adb protocol on panda (PandaBoard)
SUBSYSTEM=="usb", ATTR{idVendor}=="0451", ATTR{idProduct}=="d101", MODE="0600", OWNER="##votre_nom_d_utilisateur##"
# fastboot protocol on panda (PandaBoard)
SUBSYSTEM=="usb", ATTR{idVendor}=="0451", ATTR{idProduct}=="d022", MODE="0600", OWNER="##votre_nom_d_utilisateur##"
# usbboot protocol on panda (PandaBoard)
SUBSYSTEM=="usb", ATTR{idVendor}=="0451", ATTR{idProduct}=="d010", MODE="0600", OWNER="##votre_nom_d_utilisateur##"

On relance le service udev

chris@tux:~/tmp/yakju-imm76i$ sudo service udev restart

Télécharger et décompresser la mise à jour Factory Images « yakju » for Galaxy Nexus « maguro » (GSM/HSPA+) (pas besoin de Google Wallet en France pour la majorité d’entre nous) depuis le site de Google : https://developers.google.com/android/nexus/images?hl=fr-FR#yakju

Démarrer le Google Nexus en mode fastboot en appuyant simultanément sur les boutons : Volume+ et Volume- et PowerOnOff

Se rendre dans le répertoire où l’image à été décompressé pour débloquer le mode fastboot

chris@tux:~/tmp/yakju-imm76i$ fastboot oem unlock
...
OKAY [ 25.900s]
finished. total time: 25.900s

Lancer la mise à complète d’ICS 4.0.4

chris@tux:~/tmp/yakju-imm76i$ ./flash-all.sh
sending 'bootloader' (2308 KB)...
OKAY [  0.318s]
writing 'bootloader'...
OKAY [  0.292s]
finished. total time: 0.610s
rebooting into bootloader...
OKAY [  0.006s]
finished. total time: 0.006s
sending 'radio' (12288 KB)...
OKAY [  1.736s]
writing 'radio'...
OKAY [  1.379s]
finished. total time: 3.116s
rebooting into bootloader...
OKAY [  0.006s]
finished. total time: 0.007s
archive does not contain 'boot.sig'
archive does not contain 'recovery.sig'
archive does not contain 'system.sig'
--------------------------------------------
Bootloader Version...: PRIMELA03
Baseband Version.....: I9250XXLA2
Serial Number........: 0146B0000101601D
--------------------------------------------
checking product...
OKAY [  0.007s]
checking version-bootloader...
OKAY [  0.008s]
checking version-baseband...
OKAY [  0.008s]
sending 'boot' (4148 KB)...
OKAY [  0.577s]
writing 'boot'...
OKAY [  0.252s]
sending 'recovery' (4478 KB)...
OKAY [  0.638s]
writing 'recovery'...
OKAY [  0.310s]
sending 'system' (316111 KB)...
OKAY [ 44.125s]
writing 'system'...
OKAY [ 33.302s]
erasing 'userdata'...
OKAY [  0.315s]
erasing 'cache'...
OKAY [  0.013s]
rebooting...

finished. total time: 79.598s

Rebooter en mode fastboot pour remettre le lock par soucis de sécurité

chris@tux:~/tmp/yakju-imm76i$ fastboot oem lock
...
OKAY [  0.170s]
finished. total time: 0.170s

Je suis enfin à jour et je gagne en performance, c’est fluide !!!

Installer Amazon MP3 Downloader sur Ubuntu 11.10

Avec Ubuntu Oneiric (11.10), impossible d’installer l’application de téléchargement des mp3s d’Amazon (Amazon MP3 Downloader).
Pour cause les librairies libboost sont trop récentes et ne sont pas retrouveés dynamiquement par le programme AmazonMP3 Downloader ; je crois qu’il vaut mieux pour amazon travailler sur la compilation statique du produit. Ci-dessous les étapes pour pallier le problème (basées sur une discussion ubuntuforums) :

mkdir -p $HOME/tmp/amazonmp3_oneiric
cd $HOME/tmp/amazonmp3_oneiric

Télécharger les fichier .deb :

wget https://launchpadlibrarian.net/26959932/libboost-signals1.34.1_1.34.1-16ubuntu1_i386.deb https://launchpadlibrarian.net/26959936/libboost-thread1.34.1_1.34.1-16ubuntu1_i386.deb https://launchpadlibrarian.net/26959922/libboost-iostreams1.34.1_1.34.1-16ubuntu1_i386.deb https://launchpadlibrarian.net/26959918/libboost-filesystem1.34.1_1.34.1-16ubuntu1_i386.deb https://launchpadlibrarian.net/26959916/libboost-date-time1.34.1_1.34.1-16ubuntu1_i386.deb https://launchpadlibrarian.net/26959928/libboost-regex1.34.1_1.34.1-16ubuntu1_i386.deb https://launchpadlibrarian.net/34165098/libicu40_4.0.1-2ubuntu2_i386.deb
sudo dpkg -i lib*.deb

Télécharger et installer l’application Amazon MP3 Downloader : http://www.amazon.com/gp/dmusic/help/amd.html?ie=UTF8&forceos=Linux.
Pour l’installation, il est possible d’utiliser les détails fournis par amazon sur la page de téléchargement ou en mode console :

sudo dpkg -i AmazonMP3DownloaderInstall.deb

Et voilà.

Discussions qui traitent aussi du sujet :

 

Installer ImageMagick chez l’hébergeur DreamHost

J’ai récemment commencé à utiliser RVM, le gestionnaire des versions de ruby, sur mon compte mutualisé Dreamhost. En réinstallant mes gems j’ai été confronté à une erreur concernant la compilation d’ImageMagick nécessaire au gem rmagick. En effet la librairie RMagick2.so n’est trouvée car systématique recherchée dans /usr/local/lib.
Type d’erreur :

LoadError: libMagickCore.so.2: cannot open shared object file: No such file or directory - $HOME/.rvm/gems/ruby-1.8.7-head@monprojet/gems/rmagick-2.13.1/lib/RMagick2.so

L’astuce est de compiler ImageMagick en précisant au compilateur où trouver les librairies compilées et installées par mes soins.
Ci-dessous la ligende commande qui permet à la librarie de s’installer et rechercher où il faut les dépendances :

LDFLAGS="-L$HOME/opt/lib -Wl,-rpath,$HOME/opt/lib"
LD_LIBRARY_PATH=/home/congopro/opt/lib
./configure --prefix=/home/congopro/opt --with-gslib --with-gs-font-dir=/usr/share/fonts/type1/gsfonts/ --without-perl --without-magick-plus-plus

J’ai par la même occasion complétée la procédure de compilation disponible sur le wiki de Dreamhost : http://wiki.dreamhost.com/Image_Magick#Compiling_ImageMagick_on_your_DreamHost_account

Nuit du Hack 2011 à Disneyland Paris

C’est hier, samedi 18 juin 2011 que se déroulait la Nuit du Hack 2011. 22 heures et 30 minutes de conférences et ateliers axés sur les techniques de hacking même non numériques tels que le crochetage de serrures…

Pub Nuit du Hack 2011

Nuit du Hack 2011

Je vous invite à aller sur le site de la Nuit du Hack pour connaître le détail du programme et vous faire une idée des sujets de hacking du moment.

Personnellement j’ai du quitter cet évènement dimanche vers 1h00 du matin car je devais courir aux 10km L’Équipe à Paris (couru en 00:51:47, je visais 00:48:00)…

Les ateliers ainsi que le concours de hacking ont débuté avec des sujets très intéressants et passionnants :

  • Concours de hacking de type capture de flag : attaques d’ennemis et défenses de son réseau
  • Etude d’un test d’intrusion via Metasploit
  • Electronique programmable et systèmes libres
  • Atelier d’initiation à la cryptographie et l’utilisation des GPUs
  • Initiation ARM pour plateforme mobile
  • Crochetage basique, serrure haut sécurité, Impression
  • etc…