Есть ли прагма для того, чтобы не заботиться о макете структуры / класса? Если нет, то почему?

0

Существуют различные pragma для управления компоновкой struct/class, например, pragma pack. Но, насколько я знаю, нет pragma для того, чтобы сказать: "Меня не волнует макет. Он внутренний, код не полагается на него. Заменяйте его для лучшей производительности/размера". AFAIK, это типичный случай, и во многих случаях он может улучшить производительность и размер. Кроме того, даже если программист был достаточно осторожен, чтобы переупорядочить его для производительности/размера, у другой целевой архитектуры может быть другой оптимальный макет.

Изменить: уточнить, я говорю о порядке членов. Прокладка уже контролируема.

Кроме того, PVS-Studio имеет соответствующее сообщение. Это то, о чем я говорю - почему это невозможно сделать компилятором с pragma?

  • 0
    Вы имеете в виду что-то, что позволило бы, скажем, переупорядочить элементы данных?
  • 0
    @juanchopanza: Похоже, Пол спрашивает о набивке.
Показать ещё 6 комментариев
Теги:
struct

2 ответа

1
Лучший ответ

Такая прагма будет разрешена стандартом языка, но я не знаю ни одного компилятора, который реализует такую вещь.

В C поведение #pragma указано в разделе 6.10.6 стандарта (ссылка относится к последнему черновику):

Директива предварительной обработки формы
# pragma pp-tokens optnew-line
где токен предварительной обработки STDC не сразу следует за pragma в директиве (до любой замены макроса), приводит к тому, что реализация ведет себя определенным образом. Поведение может привести к ошибке перевода или привести к тому, что переводчик или результирующая программа будут вести себя несоответствующим образом. Любая такая прагма, которая не распознается реализацией, игнорируется.

Таким образом, # #pragma может, по сути, нарушать правила языка.

Соответствующее правило в этом случае состоит в том, что члены структуры выкладываются в том порядке, в котором они объявлены. 6.7.2.1 пункт 15:

Внутри объекта структуры члены небитового поля и единицы, в которых расположены битовые поля, имеют адреса, которые увеличиваются в том порядке, в котором они объявлены. Указатель на объект структуры, соответствующим образом преобразованный, указывает на его первоначальный член (или если этот элемент является битовым полем, а затем блоку, в котором он находится) и наоборот. В структурном объекте может быть неназванное дополнение, но не в начале.

Плохая новость: стандарт C требует, чтобы члены структуры были выложены в том порядке, в котором они объявлены. Первый член должен быть со смещением 0. Может быть произвольное отступы между членами или после последнего, но они не могут быть переупорядочены.

Хорошая новость. Язык позволяет реализации определить #pragma которая указывает макет, который нарушает вышеуказанное правило.

Плохие новости: насколько я знаю, реализация на самом деле не делает этого. Даже если бы это было так, есть другие реализации, которые этого не делают, поэтому любой код, который использует такую #pragma, будет не переносимым. (Хотя, по крайней мере, если имя #pragma уникально, любые компиляторы, которые его не распознают, должны игнорировать его, поэтому ваш код все равно будет компилироваться.)

Это для C. Правила C++ для #pragma очень похожи на правила C. Я достаточно уверен, что правила C++ для компоновки структуры также похожи на C; Наследование делает вещи немного более сложными.

2

Язык специально указывает, что члены класса будут упорядочены в памяти так же, как и на каждом уровне доступа (например, private). Прагма не может отменить это поведение.

См. 9.2/14:

Нестационарные члены данных (non-union) класса с одним и тем же контролем доступа (раздел 11) распределяются так, что более поздние члены имеют более высокие адреса в объекте класса. Порядок распределения нестатических элементов данных с различным контролем доступа неуточнен

Имейте в виду, что члены, переупорядочивающие, меняют порядок, в котором будут называться конструкторы и деструкторы субъектов, и, возможно, другие вещи. Кажется крайне рискованным даже при условии, что компилятор может сделать такие изменения за кулисами (что, если у вас есть член, который зависит от инициализации другого участника).

  • 1
    Обратите внимание, например, на два атрибута в этом ответе: stackoverflow.com/a/11770476/47453 Оба из них изменяют структуру структуры способом, который запрещен стандартами C и C ++. Но они все еще существуют. Они просто вызывают нестандартное поведение.
  • 0
    Я думал, что это был порядок, в котором они объявлены в классе, независимо от уровня доступа.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню