L’ordre en mémoire est-il garanti pour les membres privés de la classe en C ++?

class my_class_t { private: uint64_t field1; uint64_t field2; }; 

Est-ce que l’ordre de field1 et field1 garanti en mémoire par C ++ Standard?

UPD. Les réponses ont indiqué que field2 était le cas, mais que &field2 n’était peut-être pas égal à &field1 + 1 . Comment s’assurer que field2 sera immédiatement après field1 ?

Ils ont la garantie d’avoir des adresses croissantes les unes par rapport aux autres ( [class.mem] / 13 ):

Les membres de données non statiques d’une classe (non syndiquée) avec le même contrôle d’access (Clause [class.access]) sont alloués de sorte que les membres ultérieurs aient des adresses plus élevées dans un object de classe.

Notez le texte que j’ai marqué en gras. Bien qu’il soit garanti que field2 trouve après field1 lorsqu’ils sont tous les deux privés, ce n’est pas nécessairement le cas s’ils disposaient d’un contrôle d’access différent. Et bien sûr, le rembourrage intermédiaire est toujours une option.

Mais si vous voulez forcer l’absence de padding, et qu’ils soient du même type, un tableau le ferait:

 uint64_t field[2]; 

Cela rend aussi &field[0] + 1 bien défini, puisque ces objects sont maintenant évidemment membres du même tableau.

Oui, la commande est garantie.

L’adresse de field1 doit être la même que l’adresse d’une instance de my_class_t . field2 a une adresse “supérieure” à field1 dans la mesure où l’arithmétique de pointeur positif sur un pointeur unsigned char* obtenu par une reinterpret_cast field1 sur l’adresse de field1 atteindra éventuellement la mémoire occupée par field2 .

Mais notez que le comportement lors de la tentative “d’atteindre” field2 par arithmétique de pointeur sur un pointeur sur field1 n’est pas défini .

Pour vous assurer qu’il n’y a pas de remplissage entre les membres, vous ne pouvez pas le faire en C ++ portable. Mais vous pouvez utiliser un type de tableau:

 class my_class_t { private: uint64_t fields[2]; }; 

ce qui garantirait cela. Et vous pouvez ensuite atteindre les membres en utilisant l’arithmétique de pointeur.

L’ordre des objects en mémoire sera le même que l’ordre de déclaration lorsque le qualificateur d’access n’interviendra pas.