Проблемы хранения и выравнивания типов вариантов - PullRequest
0 голосов
/ 24 марта 2011

Я сделал тип варианта для использования вместо boost :: Вариант. Мой работает по сохранению индекса текущего типа в списке возможных типов и хранению данных в байтовом массиве с достаточным пространством для хранения самого большого типа.

unsigned char data[my_types::max_size];
int type;

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

template<typename T>
void set(T a) {
   int t = type_index(T);
   if (t != -1) {
      type = t;
      puts("writing atom data");
      *((T *) data) = a; //THIS PART CRASHES!!!!
      puts("did it!");
    } else {
      throw atom_bad_assignment;
    }
}

Сбой строки, которая сохраняет данные во внутренний буфер. Как видите, я просто приведу байтовый массив непосредственно к указателю нужного типа. Это дает мне неправильные адресные сигналы и ошибки шины при попытке записать некоторые значения.

Я использую GCC в 64-битной системе. Как установить выравнивание для байтового массива, чтобы убедиться, что адрес массива выровнен по 64-битной схеме? (или правильно выровнен для любой архитектуры, на которую я мог бы перенести этот проект).

РЕДАКТИРОВАТЬ: Спасибо всем, но ошибка была в другом месте. По-видимому, Intel на самом деле не заботится о выравнивании. Выравнивание выполняется быстрее, но не обязательно, и программа работает нормально таким образом. Моя проблема заключалась в том, что я не очищал буфер данных перед записью, и это вызывало проблемы с конструкторами некоторых типов. Однако я не буду отмечать вопрос как ответивший, поэтому больше людей могут дать мне советы по выравниванию;)

Ответы [ 2 ]

1 голос
/ 24 марта 2011

См. http://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/Variable-Attributes.html

unsigned char data[my_types::max_size] __attribute__ ((aligned));
int type;
0 голосов
/ 24 марта 2011

Я верю

#pragma pack(64)

будет работать на всех современных компиляторах; это определенно работает на GCC .

Более правильное решение (которое не мешает глобальной упаковке) было бы:

#pragma pack(push, 64)
// define union here
#pragma pack(pop)
...