Правила выравнивания структуры [дубликат]

Другие два варианта:

Базовый пакет:

df <- unstack(dat1, form = value ~ numbers)
rownames(df) <- unique(dat1$name)
df

sqldf package:

library(sqldf)
sqldf('SELECT name,
      MAX(CASE WHEN numbers = 1 THEN value ELSE NULL END) x1, 
      MAX(CASE WHEN numbers = 2 THEN value ELSE NULL END) x2,
      MAX(CASE WHEN numbers = 3 THEN value ELSE NULL END) x3,
      MAX(CASE WHEN numbers = 4 THEN value ELSE NULL END) x4
      FROM dat1
      GROUP BY name')
28
задан Kevin Panko 18 July 2011 в 17:12
поделиться

1 ответ

Элементы класса и структуры требуются стандартом для хранения в памяти в том же порядке, в котором они объявлены. Таким образом, в вашем примере было бы невозможно, чтобы d отображался до b.

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

Вы можете минимизировать заполнение путем изменения порядка членов, увеличивая или уменьшая порядок размеров. Или у вашего компилятора может быть опция #pragma pack или что-то подобное, что будет стремиться минимизировать заполнение при возможном расходе производительности и размера кода. Прочитайте документы для своего компилятора.

56
ответ дан Graham Borland 22 August 2018 в 07:07
поделиться
  • 1
    GCC-эквивалент #pragma pack равен __attribute__ ((packed)). В C ++ 11 это стандартизируется с атрибутом alignas. – R. Martinho Fernandes 18 July 2011 в 10:15
  • 2
    В частности, требование для членов данных, находящихся в одном и том же порядке в памяти, кодируется в 9.2.12 (нестатические члены данных (неединичного) класса, объявленные без промежуточного спецификатора доступа, распределяются так, что более поздние члены имеют более высокие адреса в пределах класса [...]) стандарта ISO / IEC 14882: 2003. – Martin Sojka 18 July 2011 в 10:22
  • 3
    @Kevin - Стандарт C говорит так, потому что именно так он работал, когда C был стандартизирован. Предположительно, некоторые "умные" код воспользовался этим. – Bo Persson 18 July 2011 в 18:23
  • 4
    @Kevin. Общий трюк старой школы для объявления объектов с заголовком и телом переменной длины заключается в том, чтобы закончить структуру заголовка фиктивным массивом длиной один (или нулевой длиной, если это позволяет компилятор), а затем malloc sizeof (header) + length_of_body. Затем вы можете индексировать тело, используя фиктивный массив. Если манекен можно переупорядочить до начала структуры, это не сработает. – Russell Borogove 18 July 2011 в 18:36
  • 5
    @Kevin: По большей части вы можете представлять области ОЗУ, сопоставленные с аппаратными регистрами, сетевыми протоколами, форматами файлов и аналогичными структурами, такими как C-структуры. – Martin Sojka 18 July 2011 в 23:00
Другие вопросы по тегам:

Похожие вопросы: