Visual Studio 2012 adopte le look Metro

La version béta de Visual Studio 2012 (vs11) n’est pas encore disponible. Elle ne sortira que le 29 février 2012. Mais quelques captures d’écrans de cette version se sont retrouvées sur le blog Microsoft Windows Store for developers.

La version “Developer Preview” de Visual Studio 2012, qui était sortie en septembre 2011, avait le même look que Visual Studio 2010 :

vs11-look-vs2010
Visual Studio 2012 – pré-version sortie en Septembre 2011

La version béta de Visual Studio 2012 qui sortira le 29 février 2012 aura un look Metro : moins d’icônes, des onglets épurés…

visual-studio-2012-beta-metro-look

visual-studio-2012-beta-metro-look2

Un peu triste ?

Est-ce que l’interface utilisateur de Visual Studio 2012 est toujours écrite avec WPF ? Si ce n’est plus le cas, on peut espérer d’importants gains de performance…

visual-studio-2012-xaml-editor
Cliquer sur l’image pour l’agrandir

Cette version est la 11eme de Visual C++, donc son nom officiel est pour l’instant Visual Studio 11. Mais il est quasiment sûr qu’elle s’appellera Visual Studio 2012.

Mise à jour du 23 février 2012 : tous les détails du changement de look sont sur le blog Visual Studio http://blogs.msdn.com/b/visualstudio/archive/2012/02/23/introducing-the-new-developer-experience.aspx

Pourquoi l’implementation de std::shared_ptr est meilleure dans Visual C++ 2012 que dans les autres librairies C++ (boost, gcc, …)

Eh oui, pourquoi l’implémentation de std::shared_ptr est meilleure dans Visual C++ 2012 que dans les autres compilateurs ?

“Parce qu’elle utilise moins de mémoire, et qu’elle est plus rapide”.

Cette réponse est à l’image de la librairie STL : concise, efficace, mystérieuse ;).C’est aussi un prétexte à creuser le fonctionnement interne de shared_ptr. Allons-y.

 

Comment fonctionne un shared_ptr ?

En fait, un shared_ptr est un peu plus qu’un pointeur et un compteur de références. Comme la plupart du code des STL, shared_ptr est un code très dense, et… intelligent !

Un shared_ptr est un objet contenant deux pointeurs, soit 8 ou 16 octets selon qu’on compile en 32 ou 64 bits.

Voici un tout petit extrait de la définition de la classe _Ptr_base, qui sert de base pour shared_ptr et weak_ptr:

template<class _Ty>
class _Ptr_base
{    // base class for shared_ptr and weak_ptr
// ....
private:
    _Ty *_Ptr;
    _Ref_count_base *_Rep;
};

On y repère _Ptr, le pointeur vers l’objet lui-même, et _Rep, le pointeur vers un objet de type _Ref_count_base.

L’objet _Ref_count_base contient les compteurs de référence :

template<class _Ty>
class _Ref_count_base
{
private:
    long _Uses;
    long _Weaks;
    _Ty * _Ptr;
    // ...
};

Cette classe contient deux compteurs de références, en plus du pointeur vers l’objet lui-même :

  • un compteur de références pour les shared_ptr (strong ref)
  • un compteur de références pour les weak_ptr qui pointent vers l’objet (weak ref)

La création d’un shared_ptr provoque la création de deux objets :

  • l’objet shared_ptr lui même (dérivant de _Ptr_base), qui contient deux pointeurs
  • un objet de type _Ref_count_base, qui contient les compteurs de références.

Et c’est sans compter l’objet sur lequel pointe le shared_ptr ! Cela fait trois objets en tout, pour un seul shared_ptr !

image

 

Trois objets pour avoir un seul objet et un shared_ptr. C’est ainsi que fonctionnent les shared_ptr dans boost, gcc, clang, et… Visual C++ 2010.

Evidemment, si l’on crée un deuxième shared_ptr sur le même objet, seul un nouvel objet de type _Ptr_base sera créé. Le même objet _Ref_count_base sera utilisé pour les deux shared_ptr :

image

 

Accessoirement, on peut se demander pourquoi l’on a besoin de deux objets supplémentaires. Pourquoi est-ce que le shared_ptr n’est pas simplement l’adresse de l’objet _Ref_count_base ? Pourquoi a-t’on besoin d’un objet _Ptr_base en plus d’un _Ref_count_base ? Et pourquoi le pointeur vers l’objet cible (_Ty *_Ptr) est-il dupliqué dans _Ref_count_base et dans _Ptr_base ? Eh bien tout simplement pour que l’utilisation d’un shared_ptr soit aussi rapide qu’un pointeur classique. Pour que le déréférencement d’un shared_ptr soit rapide. Le fait d’avoir un pointeur vers l’objet cible (_Ty *_Ptr) en premier dans le shared_ptr permet d’accéder à l’objet cible plus rapidement, sans utiliser d’offset.

 

 

L’optimisation de shared_ptr dans Visual C++ 2012

Mais dans Visual C++ 2012 (VS11), Microsoft a été plus malin, et a remplacé le pointeur vers l’objet cible (_Ty *Ptr) par un champ _Storage bien mystérieux :

class _Ref_count_base
{
private:
    long _Uses;
    long _Weaks;
    typename aligned_storage<sizeof (_Ty),
        alignment_of<_Ty>::value>::type _Storage;
    // ...
};

Le champ _Storage correspond à l’objet alloué. _Storage est initialisé par make_shared, à la taille de l’objet pointé par notre shared_ptr (sizeof(_Ty)). Ainsi, l’objet cible du shared_ptr est placé directement dans l’objet _Ref_count_base.

image

L’avantage est que cela représente une indirection, une allocation, et un pointeur (4 ou 8 octets) de moins. C’est à la fois peu et beaucoup.

C’est peu car cela ne représente que 4 ou 8 octets. Mais c’est énorme car un programme peut contenir des milliers de shared_ptr. La création d’un shared_ptr devient plus rapide avec make_shared, et consomme moins de mémoire. Multiplié par le nombre de shared_ptr dans une application, cela peut faire beaucoup !

Gageons que cette optimisation sera reprise par Boost et les autres compilateurs. C’est le souhait qu’a exprimé Stephan T. Lavavej, programmeurs des librairies STL dans l’équipe Visual C++, lors de la conférence Microsoft Going Native 2012 sur le langage C++.

 

(

Entre parenthèse, une petite astuce.

Lorsqu’on passe un shared_ptr à une fonction, il est recommandé d’utiliser un passage par référence const plutôt qu’un passage par valeur :

void fonc1(const shared_ptr<type> &pointeur);
void fonc2(shared_ptr<type> pointeur);

Le passage par valeur (fonc2) provoquera la création d’un nouvel objet shared_ptr et son initialisation par son move-constructor. Le passage par référence (fonc1) est plus efficace.

)

C++11 dans Visual Studio 2012

 

La version beta de Visual Studio 2012

Une version béta de Visual C++ 2012 sera disponible d’ici quelques jours, au cours du mois de février 2012. Sans doute le même jour que la version béta de Windows 8.

C’est ce qu’a annoncé Herb Sutter le 3 février 2012 à la conférence Microsoft Going Native 2012 sur le langage C++.

herb-sutter-going-native
Herb Sutter à la conférence Going Native 2012

Les nouveauté de cette version béta seront :

  • support des applications pour tablettes Windows 8 (évidemment!)
  • support des processeurs ARM : possibilité de générer du code ARM
  • support de C++AMP
  • support partiel du langage C++11
  • support complet des librairies STL de C++11, notamment les nouveaux objets thread, mutex, atomics, future, async, …

Il était prévu un support partiel de la norme C++11 dans Visual C++ 2012, comme annoncé il y a quelques mois sur le blog de l’équipe Visual C++. Ce choix a finalement été remis en cause. Le support de C++11 sera amélioré dans Visual C++ 2012. Les deux fonctionnalités suivantes de C++11 seront présentes dans la béta de Visual C++ 2012 :

int array[5] = { 1, 2, 3, 4, 5 };
for (int& x : array)
    x *= 2;

 

Des mises à jour du compilateur C++ après la sortie de Visual Studio 2012

Après la sortie de Visual Studio 2012, des mises à jour du compilateur sont prévues dans les mois qui suivront sous la forme de Feature Packs. Cela permettra d’améliorer le support de C++11 sans attendre la version suivante de Visual Studio.

Plusieurs Feature Packs sont prévus. Les fonctionnalités prévues dans ces mises à jour du compilateur VC++ 2012 ne sont pas encore gravées dans le marbre. En voici la liste des principales :

 

we_need_you

Microsoft a besoin de votre avis sur ce qu’il faut mettre dans les Feature Packs de Visual C++ 2012 ! Dites quelles sont vos fonctionnalités favorites de C++11 dans une étude en ligne.

L’étude en ligne sur C++11 est ici : bit.ly/mscpp11

Le futur du langage ISO C++ : les nouvelles librairies PCL

La norme C++11 a été publiée il y a quelque mois à peine, et l’on parle déjà de la version d’après ! Peut-être C++16 ?

C++11 est plus ou moins supporté à ce jour par les différents compilateurs C++ (visual C++, gcc, clang…). Microsoft a encore pas mal de travail, mais l’équipe Visual C++ y travaille pour la prochaine version de Visual Studio.

C++11 est devenu un langage moderne et sûr. Mais C++11 a un énorme point faible par rapport à d’autres langages, comme Java ou C#. Ce point faible, ce sont…

Les librairies du langage !

Voici une représentation de la taille des librairies de quelques langages :

  • C++ 11
  • C# et les librairies .Net de base
  • Java 7
  • C# et les librairies complètes

langage-library-size

Oui, la taille des librairies C++11 est représentée par le petit carré bleu, si petit par rapport aux librairies de C# ou de Java.

Tous les programmeurs C++ le savent, les classes du langage C++, celles qu’on est sûr de retrouver d’un compilateur à l’autre, d’un OS à l’autre, sont peu nombreuses. On doit toujours utiliser des librairies non portables.

Eh bien cela va changer.

Le comité ISO C++ va largement étoffer les librairies standard dans la prochaine version de C++, prévue d’ici quatre ou cinq ans. Ce sera les PCL, Portable C++ Libraries.

C’est ce qu’a annoncé aujourd’hui 3 février 2012 Herb Sutter lors de la conférence Microsoft Going Native 2012 sur le C++.

Toutes ces librairies existent déjà sous une forme ou une autre. On peut citer boost, poco, Qt, MFC, et bien d’autres. Et puis tous les éditeurs de logiciels ont leurs propres librairies : Microsoft Office a ses librairies C++ portables sous Windows et Mac. Idem chez Adobe, Apple, Google, Facebook, … Le problème est que ces librairies ne sont pas standard, et que l’on n’est pas sûr de pouvoir les trouver dans toutes les implémentations des compilateurs C++, sur toutes les plate-formes.

A la demande du comité ISO C++, ces acteurs de l’industrie C++ sont mis à contribution pour apporter le meilleur de leurs librairies à la norme du langage C++. Un peu comme Boost a été mis à contribution pour C++11. Microsoft (notamment l’équipe Office), Apple et Google ont déjà proposé des librairies.

future-cpp-libraries

Voici les principaux domaines qui vont être ajoutés :

Classes de bas niveau :

  • Algorithmes parallèles
  • Types futurs (future.then, continuation)
  • Entrées-sorties asynchrones (async I/O)
  • Conteneurs tolérant le multitâche (thread safe containers)
  • Accès au système de fichier
  • Réseau, sockets
  • Queues de messages (message queues)
  • Serialisation d’objets

Classes de haut niveau :

  • Services Web REST
  • Protocoles HTTP, FTP…
  • Gestion des formats HTML XML XSLT, JSON
  • Paramètres/préférences
  • Compression
  • Cryptographie
  • Traitement de fichiers Son, Image, Video
  • Traitement de bases de données
  • Envoi de SMS

Le but n’est pas de permettre le portage des applications sur plusieurs plate-formes, comme Qt. Une librairie graphique portable sur plusieurs plate-forme serait forcément moins puissante que l’API native du système d’exploitation. Le but n’est pas non plus d’être une lourde surcouche au système d’exploitation, ou de devenir une plate-forme.

On n’en sait pas beaucoup plus pour l’instant, l’essentiel de ce que dit Herb Sutter à la conférence Going Native 2012 sur le sujet est résumé ici. Ce projet vient de démarrer.

Mais quelle évolution ce sera !