web-dev-qa-db-fra.com

Les octets de remplissage d'un type POD sont-ils copiés?

Supposons que j'ai un type de POD comme celui-ci:

struct A {
    char a;
    int b;
};

Sur mon système, sizeof(A) == 8, même si sizeof(char) == 1 et sizeof(b) == 4. Cela signifie que la structure de données a 3 octets inutilisés.

Supposons maintenant que nous le fassions

A x = ...;
A y =x;

Question:

Est-il garanti que les 8 octets de x et y seront identiques, même ceux des 3 non utilisés?

De la même manière, si je transfère les octets sous-jacents de certains objets A vers un autre programme qui ne comprend pas leur signification ou leur structure et les traite comme un tableau de 8 octets, cet autre programme peut-il comparer en toute sécurité deux As pour l'égalité?

Remarque: Dans une expérience avec gcc 7 , il semble que ces octets soient copiés. Je voudrais savoir si cela est garanti.

47
Szabolcs

Le constructeur de copie/déplacement implicitement défini pour une classe non-union X effectue une copie/déplacement par membre de ses bases et membres.

12.8/15 [class.copy] dans N4141

Le modèle de bits dans les octets de remplissage peut ainsi différer.

43
Baum mit Augen

Il ne fait pas autorité, mais l'entrée de cppreference pour std::memcmp suggère que les octets de remplissage peuvent différer:

memcmp() entre deux objets de type struct{char c; int n;} comparera les octets de remplissage dont les valeurs peuvent différer lorsque les valeurs de c et n sont les mêmes

7
Tristan Brindle

étant donné que vous avez posé des questions sur un type de POD (donc y compris les unions), il convient de mentionner que, selon [class.copy]

Le constructeur de copie/déplacement implicitement défini pour une union X copie la représentation d'objet (6.9) de X

que pour les types trivialement copiables, les bits de remplissage doivent également être inclus. Il pourrait donc s'agir simplement de remplacer A par

union A{ struct {
    char a;
    int b;
}; };

(en fait, ce qui précède utilise une structure anonyme non standard, mais vous obtenez le point ...)

6
Massimiliano Janes

Répondre à votre deuxième question:

De manière équivalente, si je transfère les octets sous-jacents de certains objets A vers un autre programme qui ne comprend pas leur signification ou leur structure et les traite comme un tableau de 8 octets, cet autre programme peut-il comparer en toute sécurité deux As pour l'égalité?

Comme un objet de votre type peut contenir des octets de remplissage, un autre programme ne peut généralement pas comparer deux de ces objets pour l'égalité:

Savoir qui morceaux des octets qui composent l'objet sémantiquement est la clé pour définir son représentation de la valeur. Cependant, dans ce scénario, le programme cible ne connaît que la représentation d'objet, c'est-à-dire la séquence de octets représentant un tel objet en mémoire, y compris les octets de remplissage. Une fonction comme memcmp ne peut comparer ces objets dont la représentation de valeur est identique à sa représentation d'objet de manière significative. Si vous l'utilisez pour comparer des objets en termes de valeur même s'ils ont un remplissage, il peut ne pas donner les bons résultats car il ne peut pas dire quels bits dans la représentation d'objet ne sont pas pertinents pour que les représentations de valeur de deux objets soient égales.

Voir http://en.cppreference.com/w/cpp/language/object

4
Jodocus