C против C++ выравнивание структуры
В недавнем интервью меня спросили о выравнивании структурных полей C++, и я теоретизировал, что C и C++ придерживаются одной и той же стратегии в упаковке структур.
Но это было неверное предположение. Интервьюер сказал, что в целом C и C++ упаковывают структуры по-разному, и мы никогда не должны ожидать обратного. ИМХО это странное утверждение. Здесь нет pack "C"
квалификатор структур в C++ для использования в двуязычных заголовочных файлах C / C++.
Таким образом, на практике это может означать, что вы не можете создать структуру в C++ и передать ее в библиотеку C, потому что в общем случае ее поля будут выровнены по-другому и будут иметь разные смещения. Но на самом деле большинство программистов серьезно полагаются на эту функциональную совместимость вплоть до того момента, когда они преобразуют указатель на структуру C POD в ссылку на оболочку C++ вокруг этой структуры с помощью некоторых вспомогательных методов. Не могли бы вы уточнить этот вопрос?
3 ответа
Стандарты языка C и C++ не предъявляют требований к заполнению структуры и оставляют его за деталями реализации компилятора. Строгое толкование этого означало бы, что нет никакой гарантии, что структура будет одинаковой между ними.
На практике, однако, данная версия набора инструментов, поддерживающего как C, так и C++ (например, GCC или Clang), может при необходимости упаковывать идентичную структуру одинаковым образом. Без этого большая часть производственного кода в мире просто не будет работать. Однако это гарантия, предоставляемая набором инструментов, а не языком.
Стоит отметить, что если бы вы объявили структуру, аналогичную оригиналу C, но добавили спецификаторы доступа (private
, public
а также protected
), что компоновка изменится, но это немного растянуто, так как структура больше не идентична.
Это было совершенно очевидно неправильно (на стороне интервьюера). Ясно, что структура упаковки одинакова для C и C++ для любого, кто работал с любым низкоуровневым API, имеющим дело со структурами, например, с сетевым API. Все это функции C, которые принимают структуры C, но их безопасно вызывать миллионы миллионов раз в день из кода C++.
Вам повезет, у вас возник этот вопрос. Это дает понять, что вы не должны там работать.
Когда C++ был разработан, разработчики выяснили, что программисты C полагались на некоторые вещи, которые разработчики C++ не хотели гарантировать, но не гарантируя их, это означало бы, что большая часть кода C, который был также допустимым кодом C++, будет нарушена при использовании. как код C++. Не желательно
Вот почему они изобрели структуры "POD": структура, которая не использует никаких функций C++, будет вести себя в программе на C++ точно так же, как в программе на C (кроме того факта, что поведение, определяемое реализацией, может измениться, поскольку компилятор C и Компилятор C++ явно не та же реализация. С другой стороны, компилятор C++, вероятно, просто скопирует определение реализации из компилятора C).
Если вы берете любую простую структуру C, которая также является допустимой структурой C++ (например, нет элементов с именем "class"), а затем вы просто добавляете "public:" сразу после открывающей фигурной скобки, то ее макет, порядок элементов, выравнивание и так далее все может измениться. Несмотря на то, что все члены структуры по умолчанию общедоступны, ничего не изменилось. За исключением того, что из-за "public:" это больше не POD.