Размер полей структуры

Тема в разделе "LANGS.C", создана пользователем cupuyc, 12 авг 2010.

  1. cupuyc

    cupuyc New Member

    Публикаций:
    0
    Регистрация:
    2 апр 2009
    Сообщения:
    763
    Здравствуйте. Интересует такой вопрос. Я определяю структуру:
    Код (Text):
    1. struct color_t
    2. {
    3.   uint8_t r;
    4.   uint8_t g;
    5.   uint8_t b;
    6.   uint8_t a;
    7. };
    Теперь хочу скопировать структуру в битмап, типа так:
    Код (Text):
    1. uint32_t pixel;
    2. color_t color;
    3. // ...
    4. pixel = *(uint32_t*)(&color);
    Проблема в том, что я изначально не знаю какое выравнивание полей сделает компилятор. Вообще, это зависит как от конкретного компилятора, так и от его настроек. В VC есть __declspec(align(8)), но не хотелось бы привязываться к конкретному синтаксису. Единственное, что приходит в голову:
    Код (Text):
    1. struct color_t
    2. {
    3.   uint32_t r : 8;
    4.   uint32_t g : 8;
    5.   uint32_t b : 8;
    6.   uint32_t a : 8;
    7. };
     
  2. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Копируй по полям, или сделай функцию упаковки.
     
  3. cupuyc

    cupuyc New Member

    Публикаций:
    0
    Регистрация:
    2 апр 2009
    Сообщения:
    763
    не эффективно
     
  4. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Правила выравнивания у всех одинаковые - смещение поля кратно наименьшему из двух значений: либо размеру самого поля, либо значению align. Т.е. align служит не для увеличения кратности выравнивания, а наоборот для ее ограничения.
    Поэтому в структуре, состоящей только из одних однобайтовых полей, все эти поля будут "выравнены" на 1 независимо от align, и только общий размер структуры м.б. увеличен, если он окажется не кратен 4-м
     
  5. cupuyc

    cupuyc New Member

    Публикаций:
    0
    Регистрация:
    2 апр 2009
    Сообщения:
    763
    leo, это справедливо для любой процессорной архитектуры? это вообще стандартизовано?
     
  6. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    > Поэтому в структуре, состоящей только из одних однобайтовых полей, все эти поля будут "выравнены" на 1 независимо от align, и только общий размер структуры м.б. увеличен, если он окажется не кратен 4-м
    пруфлинк нужен :)
    желательно на стандарт.
     
  7. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Конечно нет.
    Это "негласное" правило для x86, вытекающее из рекомендаций Intel\AMD выравнивать данные на "натуральный размер операнда"
     
  8. cupuyc

    cupuyc New Member

    Публикаций:
    0
    Регистрация:
    2 апр 2009
    Сообщения:
    763
    n0name, вот и я о том-же. Я хочу разобраться как сделать рабочий код по стандарту. Домыслы, рекомендации, костыли мне не нужны - и так не трудно догадаться как сделать рабочий вариант.
     
  9. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    cupuyc
    Тогда либо сразу делай "не эффективно", либо положись еще на один домысел\костыль - надежду на оптимизирующие возможности компилятора или процессора:
    Код (Text):
    1. if (sizeof(color_t) == sizeof(uint32_t)) {
    2.   pixel = *(uint32_t*)(&color);
    3. }
    4. else
    5.   ...
    Если размеры совпадают, то либо оптимизирующий компилятор выбросит из кода и проверку размера и ветку else, ну либо процессор с предсказанием ветвлений ошибется макс. 1 раз и затем будет ходить только по "эффективной" ветке :)
     
  10. cupuyc

    cupuyc New Member

    Публикаций:
    0
    Регистрация:
    2 апр 2009
    Сообщения:
    763
    leo, ещё раз повторю. Вопрос не стоит как вставить костыль. Вопрос стоит как сделать по стандарту. До подобных костылей я и сам могу догадаться.

    Сейчас гляну что даёт оптимизация. Будет ли она конструкцию, типа
    заменять на обычное присвоение...
     
  11. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Стандарт.
    Но что касается отдельных полей в pod структуре, то тут стандарт ничего не говорит. В общем гарантий того, что данные будут лежать плотно, безусловно нет.
     
  12. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    cupuyc
    Что в приведенном коде #9 не соответствует стандарту ?!

    Зачем ?! На всех возможных компиляторах под все процессоры глянешь ?! :lol:
     
  13. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    > Но что касается отдельных полей в pod структуре, то тут стандарт ничего не говорит.
    почему же, кое-что есть:
    Этот фрагмент как раз и говорит нам о том, что выравнивание в структуре зависит от реализации компилятора.
     
  14. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    n0name
    Безусловно и это тоже.
     
  15. cupuyc

    cupuyc New Member

    Публикаций:
    0
    Регистрация:
    2 апр 2009
    Сообщения:
    763
    Booster, спасибо.

    Компилятор делает гадость.. Оптимизация не помогает..
     
  16. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Ха-ха (злорадно). А вот с вариантом #9 наверняка поможет ;)
     
  17. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    с битфилдами в общем случае тоже не прокатит, ибо различнык системы могут юзаться, как LE так и BE
     
  18. cupuyc

    cupuyc New Member

    Публикаций:
    0
    Регистрация:
    2 апр 2009
    Сообщения:
    763
    n0name, Booster, т.е. безкостыльных выходов нет?
     
  19. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    cupuyc
    Вот чудак-человек, в чем ты видишь костыль, если согласно тому же стандарту размер структуры зависит от реализации компилятора и следовательно ты его не можешь знать заранее и поэтому "якобы" проверяешь в рантайме ? Копировать 4 байта из структуры в uint32 стандарт тоже не запрещает - значит все законно и в рамках стандарта. Ну а конкретный компилятор под конкретную платформу уже сам решит как оптимизировать этот код
     
  20. nanoo

    nanoo New Member

    Публикаций:
    0
    Регистрация:
    6 авг 2010
    Сообщения:
    23
    Код (Text):
    1. struct {
    2.   union {
    3.      uint32_t bbb;
    4.      struct {
    5.          uint8_t a;
    6.          uint8_t r;
    7.          uint8_t g;
    8.          uint8_t b;
    9.      } ddd;
    10.   }
    11. } st;
    12.  
    13. ....
    14.  
    15. st.ddd.a = 0xff;
    16. st.ddd.r = red;
    17. st.ddd.g = green;
    18. st.ddd.b = blue;
    19.  
    20. pixel = &(st.bbb);
    Для всех машин с одинаковой endianess будет работать одинаково.
    Для остальных - поменять порядок переменных в ddd.