В недавнем интервью меня спросили о выравнивании структурных полей C ++, и я теоретизировал, что C и C ++ придерживаются одной и той же стратегии в упаковке структур.
Но это было неверное предположение. Интервьюер сказал, что в целом C и C ++ упаковывают структуры по-разному, и мы никогда не должны ожидать обратного. ИМХО это странное утверждение. Здесь нет pack "C"
квалификатор структур в C ++ для использования в двуязычных заголовочных файлах C / C ++.
Таким образом, на практике это может означать, что вы не можете создать структуру в C ++ и передать ее в библиотеку C, потому что в общем случае ее поля будут выровнены по-другому и будут иметь разные смещения. Но, на самом деле, большинство программистов серьезно полагаются на эту функциональную совместимость вплоть до того момента, когда они преобразуют указатель в C POD struct для ссылки на оболочку C ++ вокруг этой структуры с некоторыми вспомогательными методами. Не могли бы вы уточнить этот вопрос?
Стандарты языка 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.