C vs С++ struct alignment

В недавнем интервью мне рассказали о выравнивании структурных полей С++ и теоретизировали, что C и С++ следуют той же стратегии в структурированной упаковке.

Ховер, это было неправильное предположение. Интервьюер сказал, что в целом C и С++ упаковывают структуры по-разному, и мы никогда не должны ожидать противоположного. ИМХО это странное выражение. Существует не pack "C" квалификатор для структур в С++ для использования в двуязычных заголовочных файлах C/С++.

Таким образом, на практике это может означать, что вы не можете создать структуру на С++ и передать ее в библиотеку C, потому что в целом ее поля будут выровнены по-другому и будут иметь разные смещения. Но на самом деле большинство программистов серьезно полагаются на эту интероперабельность до того момента, когда они преобразуют указатель на структуру C POD в ссылку на С++ обертка вокруг этой структуры с помощью некоторых вспомогательных методов. Не могли бы вы прояснить этот вопрос?

Ответ 1

Оба языка языка C и С++ не требуют требований к заполнению структуры и оставляют это детализацией реализации компилятора. Строгая интерпретация этого означает, что нет никакой гарантии, что структура будет одинаковой между двумя.

На практике, однако, данная версия инструментальной цепочки, способная как для C, так и для С++ (например, GCC или Clang), может при необходимости упаковать одну и ту же структуру. Без этого много производственного кода в мире просто не получится. Однако это гарантия, предоставляемая инструментальной цепочкой, а не язык.

Стоит отметить, что если бы вы объявили аналогичную структуру исходным C, но добавили спецификаторы доступа (private, public и protected), то макет изменился, но немного растяжение, поскольку структура больше не идентична.

Ответ 2

Это было наиболее очевидно неправильно (на стороне интервьюера). Ясно, что структура упаковки одинакова для C и С++ для тех, кто работал с любым низкоуровневым API, касающимся структур - например, сетевого API. Все это C-функции, которые принимают структуры C, но они безопасно называют миллионы миллионов раз в один день из кода С++.

Вам должно быть повезло, что у вас был этот вопрос. Это дает понять, что вы не должны там работать.

Ответ 3

Когда С++ был разработан, разработчики выяснили, что программисты C полагаются на некоторые вещи, которые разработчики С++ не хотели гарантировать, но не гарантируя их, означало бы, что много кода C, который также был действительным, С++-кодом был бы ломается при использовании в качестве кода на С++. Нежелательно.

Вот почему они изобрели структуры "POD": структура, которая не использовала никаких функций С++, могла бы вести себя в С++-программе точно так же, как в программе C (кроме того, что поведение, определенное реализацией, может измениться, поскольку Компилятор C и компилятор С++ явно не являются одной и той же реализацией. С другой стороны, компилятор С++, вероятно, просто скопирует определение реализации из компилятора C).

Если вы берете какую-либо простую C-структуру, которая также является допустимой структурой С++ (например, не члены с именем "class" ), а затем вы просто добавляете "public:" сразу после открытия скобки, тогда ее макет, порядок члены, выравнивание и т.д. все могут измениться. Хотя все члены структуры по умолчанию являются общедоступными, поэтому ничего не изменилось. За исключением того, что из-за "общественности" это больше не POD.