Notez que cette réponse a été légèrement réécrite et que le résultat final est devenu l'opposé de ce qu'il était auparavant. Merci à @ David Rodríguez - dribeas pour m'avoir éclairé. :)
Il s'agit d'un bug. Clang 3.2 trunk et GCC 4.7+ sont aussi d'accord et vont initialiser les membres.
C'est l'heure du langage standard. Notez que T x{};
(ou = {}
) peut être interprété comme une initialisation de liste. ou initialisation de l'agrégat. A
ici n'est pas un agrégat car il possède des membres privés, et en tant que tel ne peut pas être initialisé par ce dernier.
§8.5.1 [dcl.init.aggr] p1
Un site agrégat est un tableau ou une classe (clause 9) ne comportant [...] aucun membre de données non statique privé ou protégé [...].
Il ne reste plus que l'initialisation de la liste, ce qui initialisera les deux éléments suivants a1
y a2
.
§8.5.1 [dcl.init.list] p3
Initialisation par liste d'un objet ou d'une référence de type T
est défini comme suit :
- Si la liste d'initialisation ne comporte aucun élément et que
T
est un type de classe avec un constructeur par défaut, l'objet est initialisé par une valeur.
L'initialisation des valeurs est spécifiée comme suit pour notre cas spécifique :
§8.5 [dcl.init] p7
si T
est un type de classe non unitaire (éventuellement qualifié cv) sans constructeur fourni par l'utilisateur, alors l'objet est zéro initialisé [...].
Et cela signifie à son tour que les membres doivent être mis à zéro.