2015-11-20 2 views
62

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

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

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

+13

Какой странный вопрос. Если бы структура отступов отличалась между C и C++, я был бы прикручен.Возможно, интервьюер нашел какой-то действительно странный прием на каком-то неясном компиляторе - или, может быть, он думал, что компиляторы C и C++ могут быть совершенно разными, и ожидая, что два компилятора будут выравнивать поля одинаково с одинаковым дополнением, возможно, не то, уверенно полагаться (но это будет справедливо даже между двумя компиляторами C или двумя компиляторами на C++ - имеет мало общего с языком). –

+17

Вы правы. Упаковка - это деталь реализации процессора, она обеспечивает соблюдение правил выравнивания. Компилятор C и компилятор C++, предназначенные для одного и того же процессора, должны иметь дело с одной и той же деталью реализации. –

+1

Выравнивание структуры определяется на уровне компилятора и зависит от архитектуры процессора. Компиляторы больше всего похожи на совместимые выравнивания в одном наборе (GCC, Clang/LLVM) из-за требований ABI, но могут иметь разные правила между собой. – myaut

ответ

68

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

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

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

+1

Да, и если вы добавите виртуальную функцию, это тоже будет по-другому. Аналогично. – SergeyA

+0

Примечание: перечитайте текст. У вас есть дубликат текста. – Olaf

+0

Thiings могут быть разными, если в C++ есть скрытые поля, например. для виртуальных функций и RTTI. – Olaf

29

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

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

+9

Мне нравится этот ответ (хотя мне нравится и другой), как практический и заслуженно утешительный. Похоже, что у интервьюера была эта странная концепция в его голове больше, чем он пытался заставить людей думать об этом uber-теоретическом способе относительно гипотетических гипотез языка - главным образом из-за этой части: * «C и C++ - это структурирование структур в разных и мы никогда не должны ожидать противоположного ». Это звучит не так, как интервьюер твердо понял, о чем он говорил. Это вопрос интервью, который я ожидал бы от компании с ... –

+0

... странные стандарты кодирования, основанные на суевериях. По крайней мере, я видел этот тип. Может быть, я слишком суров. –

+5

Да, нет хороших ответов на плохой вопрос, должен быть рад не работать там –

4

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

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

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

+0

И почему вы так думаете? Конечно, пример вашего класса со всеми публичными членами (как и все частные члены, в этом отношении) - это POD. – SergeyA