Сработал бы этот союз, если бы char имел более строгие требования к выравниванию, чем int? - PullRequest
8 голосов
/ 21 декабря 2010

Недавно я натолкнулся на следующий фрагмент, который пытается обеспечить доступность всех байтов i (не более) как отдельных элементов c:

union {
  int i;
  char c[sizeof(int)];
};

Теперь это кажетсяхорошая идея, но мне интересно, допускает ли стандарт тот случай, когда требования к выравниванию для char более строгие, чем для int.

Другими словами, возможно ли иметь четыребайт int, который требуется выровнять по четырехбайтовой границе с однобайтовым char (по определению это один байт, см. ниже), который требуется выровнять по шестнадцатибайтовой границе?

И не мешает ли это использовать вышеприведенный союз?

Две вещи, на которые стоит обратить внимание.

  1. Я говорю конкретно о том, что стандарт позволяет здесь, а не о том, чтонормальный разработчик / архитектура предоставит.

  2. Я использую термин «байт» в смысле ISO C, где это ширина char, а не обязательно 8 бит.

Ответы [ 2 ]

7 голосов
/ 21 декабря 2010

Ни один тип не может иметь более строгих требований к выравниванию, чем его размер (из-за того, как работают массивы), и sizeof(char) равно 1.

В случае, если это не очевидно:

  • sizeof(T [N]) - это sizeof(T)*N.
  • sizeof в единицах char; все типы представлены в виде фиксированного числа байтов (char), это число является их размером. Подробнее см. 6.2.6 (Представление типов).
  • Учитывая T A[2];, (char *)&A[1] - (char *)&A[0] равно sizeof A[0].
  • Следовательно, требование выравнивания для T не превышает sizeof(T) (фактически оно делит sizeof(T))
1 голос
/ 21 декабря 2010

Посмотрите на эту тему . Там я поставил под сомнение полезность C Unions и есть некоторые интересные идеи. Важно то, что Стандарт вообще не обеспечивает выравнивание различных полей!

РЕДАКТИРОВАТЬ: paxdiablo, только что заметил, что вы были одним из парней, отвечающих на этот вопрос, поэтому вы, вероятно, должны быть знакомы с этим ограничением.

...