web-dev-qa-db-fra.com

Alignement des structures C vs C ++

On m'a demandé dans une récente interview à propos de l'alignement des champs de struct C++ et théorisé que C et C++ suivent la même stratégie dans l'emballage de struct.

Cependant, ce n'était pas la bonne hypothèse. L'intervieweur a déclaré qu'en général, le C et le C++ emballent les structures de différentes manières et nous ne devrions jamais nous attendre à l'inverse. À mon humble avis, c'est une déclaration étrange. Il n'y a pas pack "C" qualificatif pour les structures en C++ à utiliser dans les fichiers d'en-tête bilingues C/C++.

Donc, dans la pratique, cela pourrait signifier que vous ne pouvez pas créer une structure en C++ et la transmettre à une bibliothèque C car en général, ses champs seront alignés d'une manière différente et auront des décalages différents. Mais, en fait, la plupart des programmeurs s'appuient sérieusement sur cette interopérabilité jusqu'au moment où ils convertissent un pointeur en C POD struct en une référence au wrapper C++ autour cette structure avec quelques méthodes d'assistance. Pouvez-vous clarifier cette question?

64
Minor Threat

Les normes de langage C et C++ ne font aucune exigence de remplissage de struct et le laissent être un détail d'implémentation du compilateur. Une interprétation stricte de cela signifierait qu'il n'y a aucune garantie qu'une structure serait la même entre les deux.

En pratique, cependant, une version donnée d'une chaîne d'outils capable à la fois de C et C++ (comme GCC ou Clang) peut compresser une structure identique de la même manière, si nécessaire. Sans cela, beaucoup de code de production dans le monde ne fonctionnerait tout simplement pas. C'est une garantie donnée par la chaîne d'outils, cependant, et pas la langue.

Il convient de noter que si vous déclariez une structure similaire à l'original C, mais en ajoutant des spécificateurs d'accès (private, public et protected), la disposition changerait , mais c'est un peu exagéré car la structure n'est plus identique.

68
Sam Cristall

C'était manifestement faux (du côté de l'intervieweur). Il est clair de voir que le struct struct est le même pour C et C++ pour tous ceux qui ont travaillé avec n'importe quel bas niveau API traitant des structs - par exemple, un API réseau. Toutes ces fonctions sont C, qui acceptent les structures "C", mais elles sont appelées en toute sécurité des millions de millions de fois par jour à partir du code C++.

Vous devriez être chanceux d'avoir posé cette question. Il est clair que vous ne devriez pas y travailler.

29
SergeyA

Lorsque C++ a été développé, les développeurs ont compris que les programmeurs C s'appuyaient sur certaines choses que les développeurs C++ ne voulaient pas garantir, mais ne pas les garantir signifierait que beaucoup de code C qui était également du code C++ valide serait cassé lors de l'utilisation comme code C++. Pas souhaitable.

C'est pourquoi ils ont inventé des structures "POD": une structure qui n'utilisait aucune fonctionnalité C++ se comporterait dans un programme C++ exactement comme dans un programme C (à part le fait que le comportement défini par l'implémentation pourrait changer, car un compilateur C et un compilateur C++ n'est clairement pas la même implémentation. Par contre, le compilateur C++ copiera probablement la définition d'implémentation du compilateur C).

Si vous prenez une structure C simple qui est également une structure C++ valide (aucun membre nommé "classe", par exemple), puis vous ajoutez simplement "public:" juste après l'accolade ouvrante, puis sa disposition, l'ordre des membres, l'alignement et ainsi de suite, tout peut changer. Même si tous les membres struct sont publics par défaut, rien n'a vraiment changé. Sauf qu'à cause du "public", ce n'est plus un POD.

4
gnasher729