Есть разные pragma
s для управления макетом структуры / класса, например pragma pack
, Но, насколько я знаю, нет pragma
за то, что он сказал: «Мне нет дела до макета. Он внутренний, код не полагается на него. Переупорядочивайте его для лучшей производительности / размера». AFAIK, это типичный случай, и он может улучшить производительность / размер во многих случаях. Кроме того, даже если программист был достаточно осторожен, чтобы переупорядочить его по производительности / размеру, другая целевая архитектура может иметь другую оптимальную компоновку.
Редактировать: Чтобы уточнить, я говорю о порядке членов. Заполнение уже управляемо.
Также PVS-Studio имеет актуальный сообщение. Вот о чем я говорю — почему это не может быть сделано компилятором с pragma
?
Такая прагма была бы разрешена стандартом языка, но я не знаю ни одного компилятора, который бы реализовывал такую вещь.
В С поведение #pragma
указано в разделе 6.10.6 стандарт (ссылка на последний проект):
Директива предварительной обработки вида
# прагма PP-маркерывыбирать новая линия
где токен предварительной обработкиSTDC
не сразу
следоватьpragma
в директиве (до любой замены макроса)
заставляет реализацию вести себя в определенной реализации
манера. Такое поведение может привести к сбою перевода или вызвать
переводчик или результирующая программа ведут себя в несоответствующем
манера. Любая такая прагма, которая не распознается реализацией
игнорируется
Так что #pragma
Можно, по сути, нарушают правила языка.
Соответствующее правило в этом случае состоит в том, что члены структуры располагаются в порядке, в котором они объявлены. 6.7.2.1 пункт 15:
Внутри объекта структуры, члены не битового поля и единицы в
какие битовые поля имеют адреса, которые увеличиваются в порядке
которые они объявлены. Указатель на объект структуры, соответственно
преобразован, указывает на его начальный член (или если этот член является
битовое поле, затем к единице, в которой он находится), и наоборот.
В объекте структуры может быть безымянный отступ, но не в его
начало.
Плохая новость: стандарт C требует, чтобы члены структуры были расположены в том порядке, в котором они объявлены. Первый член должен быть со смещением 0. Может быть произвольный отступ между элементами или после последнего, но они не могут быть переупорядочены.
Хорошая новость: язык позволяет реализации определять #pragma
это определяет макет, который нарушает вышеуказанное правило.
Плохая новость: насколько я знаю, ни одна реализация на самом деле не делает это. Даже если это так, есть другие реализации, которые этого не делают, поэтому любой код, который использует такой #pragma
будет непереносимым. (Хотя, по крайней мере, если имя #pragma
является уникальным, любые компиляторы, которые не распознают его, обязаны его игнорировать, поэтому ваш код все равно будет компилироваться.)
Это для C. Правила C ++ для #pragma
очень похожи на правила C. Я вполне уверен, что правила C ++ для разметки структуры также похожи на C; наследование делает вещи немного сложнее.
Язык специально призывает к тому, что члены класса будут упорядочены в памяти так же, как они находятся на каждом уровне доступа (например, private
). Нет никакого способа, которым прагма могла бы отвергнуть это поведение.
См. 9.2 / 14:
Нестатические члены данных (не объединяющего) класса с одинаковым доступом
контроль (пункт 11) распределяются таким образом, чтобы у более поздних членов
адреса внутри объекта класса. Порядок размещения нестатических
члены данных с разным контролем доступа не определены
Имейте в виду, что переупорядочение членов изменяет порядок, в котором будут вызываться конструкторы и деструкторы подобъектов, и, возможно, другие вещи. Кажется чрезвычайно рискованным даже с учетом прагмы для компилятора вносить подобные изменения за кулисы (что, если у вас есть член, который зависит от инициализации другого члена).