Приведение увеличивает требуемое выравнивание типа цели - PullRequest
0 голосов
/ 19 февраля 2019

Я программирую на ARM и у меня есть следующий фрагмент кода (на C):

struct data {
   int x;
   char y[640];
};
unsigned int offset = 819202;
char *buf; // buf is assigned an address elsewhere in the code
struct data * testdata = (struct data *)(buf + offset) 

Я получаю следующую ошибку компиляции:

ошибка: приведение увеличивает требуемое выравниваниецелевого типа [-Werror = cast-align]

testdata указатель должен указывать на часть памяти, которая содержит массив данных типа struct data.Поэтому мне нужен указатель, чтобы позже я мог применить индекс к testdata.Смещение жестко закодировано в программе.buf получено как общая память от другого процесса.

Например, позже в коде у меня есть:

testdata[index].x = 100;

Я видел несколько примеров на SO, но я не уверен, чтоэто правильный способ справиться с этим.Есть предложения?

Ответы [ 2 ]

0 голосов
/ 19 февраля 2019

Поскольку buf является указателем на char, когда вы пишете (struct data *) (buf + offset), вы говорите: «Возьмите этот указатель на некоторый символ и сделайте его указателем на struct data». Однако struct dataдолжно быть выровнено по кратности четырех байтов 1 , но ваш buf+offset может иметь любое выравнивание.Если buf+offset имеет неправильное выравнивание, не может быть превращено в правильный указатель на struct data, и ваш компилятор сообщит вам об этой проблеме.

Решение состоит в том, чтобыу вас есть выровненный адрес, который можно использовать как указатель на struct data.Это можно сделать двумя способами:

  • Определить один или несколько struct data объектов, как с struct data MyData; или struct data MyArray[10];.
  • Выделить память для struct data объектов, какс struct data *MyPointer = malloc(SomeNumber * sizeof *MyPointer);.

При любом из вышеперечисленных компилятор обеспечит правильное выравнивание памяти для объекта struct data.Первый обычно используется только для немедленной работы с struct data, а затем сбрасывает его - он не создает объект, который вы можете вернуть из функции.Последний используется, когда вы хотите вернуть полученный struct data из функции.

Когда у вас есть эти struct data объекты, вам необходимо поместить в них данные.Желательно, чтобы вы считывали данные непосредственно в них, а не в buf.Однако, если ваш программный дизайн не облегчает это, вы можете скопировать данные из buf в struct data объекты, как с одним из:

memcpy(&MyData, buf+offset, sizeof MyData);

memcpy(MyArray, buf+offset, sizeof MyArray);

memcpy(MyPointer, buf+offset, SomeNumber * sizeof *MyPointer);

Сноска

1 Четыре типичны для структуры, содержащей int, и предполагается для этого примера.Мы знаем, что требование выравнивания больше единицы из-за сообщения компилятора.

0 голосов
/ 19 февраля 2019

Предупреждение cast-align срабатывает при попытке привести из типа с меньшим выравниванием к типу с большим выравниванием.В этом случае вы получили от char, который имеет выравнивание 1 и struct data, который (поскольку он содержит int) имеет выравнивание 4 (при условии, что int равно 4 байта).

Скореечем указатель на точку структуры в массиве символов, используйте memcpy для копирования из буфера в экземпляр структуры.

struct data testdata;
memcpy(&testdata, buf + offset, sizeof(testdata));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...