#c #embedded #iar
#c #встроенный #iar
Вопрос:
Я кодирую c в IAR Embedded workbench IDE. У меня есть следующее в заголовочном файле.
typedef union {
uint8_t payload;
struct UBX_NAV_POSLLH nav_posllh;
struct UBX_NAV_STATUS nav_status;
struct UBX_NAV_DOP nav_dop;
struct UBX_NAV_SOL nav_sol;
struct UBX_NAV_VELNED nav_velned;
struct UBX_NAV_TIMEUTC nav_timeutc;
struct UBX_NAV_SVINFO nav_svinfo;
} UBXPayload;
struct UBXHeader {
uint8_t class;
uint8_t id;
uint16_t len;
uint8_t ck_a;
uint8_t ck_b;
};
struct UBXPacket {
struct UBXHeader header;
UBXPayload payload;
};
Вот мой исходный файл:
static char *c_buffer
void myinit( )
{
c_buffer= (char*)malloc(50);
}
int myfunc(uint8_t c, char *c_buffer)
{
static uint8_t rx_count = 0;
struct UBXPacket *ubx = (struct UBXPacket *)c_buffer;
for(int i=0; i<3; i ){
ubx->payload.payload[rx_count] = c; /* Error[Pe142]: expression must have pointer- to-object type */
rx_count ;
}
}
void main( )
{
char mychar = 'h';
myinit( );
myfunc(mychar, c_buffer);
}
То же самое объединение определено следующим образом в другом примере кода, написанном для компиляции с помощью компилятора ARM GCC. Оно хорошо компилируется и хорошо работает.
typedef union {
uint8_t payload[0]; /* here [0] is placed */
struct UBX_NAV_POSLLH nav_posllh;
struct UBX_NAV_STATUS nav_status;
struct UBX_NAV_DOP nav_dop;
struct UBX_NAV_SOL nav_sol;
struct UBX_NAV_VELNED nav_velned;
struct UBX_NAV_TIMEUTC nav_timeutc;
struct UBX_NAV_SVINFO nav_svinfo;
} UBXPayload;
Но в компиляторе IAR C выдается ошибка. Пожалуйста, какие-либо предложения?
Я не понимаю следующую строку
struct UBXPacket *ubx = (struct UBXPacket *)c_buffer;
Комментарии:
1. Как свидетельствуют ваши комментарии к ответам, этот вопрос не совсем точен. Похоже, вы изменили объединение из исходного кода; исходный код компилируется в GCC, но этот код не будет работать в любом компиляторе. Вы должны подробно описать свое изменение — или лучше, просто спросите об исходной проблеме, а не о своем ошибочном решении.
Ответ №1:
В UBXPayload
объединении payload
членом является один символ, но вы используете его как массив. И когда вы превращаете его в массив, вы превращаете его в массив нулевого размера, поэтому все записи в массив будут выходить за рамки, что приведет к неопределенному поведению (так что это работает не так хорошо, как вы думаете).
Комментарии:
1. Спасибо за ответ. Я не понимаю, почему подобный код компилируется в компиляторе GCC. в чем разница? Как исправить эту ошибку.
2. @Armfan Вы исправляете ошибку, создавая
payload
ненулевой массив. Либо это действительно делает его указателем и динамически (повторно) распределяет при необходимости. И нет, если это не массив, ни один компилятор (даже GCC) не будет его компилировать.3. Вы не возражаете, если я попрошу вас обратиться к некоторому коду по следующей ссылке. Номер строки 97. reviews.openpilot.org/browse /~br=next/OpenPilot/полет /модули/… Я не понимаю, как это работает.
4. @Armfan : В этом случае элемент полезной нагрузки определяется в
ubx.h
как «массив нулевой длины» таким образомuint8_t payload[0];
. Массивы нулевой длины являются расширением GCC . В этом случае вы можете безопасно определить его какuint8_t payload[1];
, поскольку все остальные члены в любом случае длиннее 1 байта. Однако, если вы получаете доступ черезpayload
за пределами заявленных границ, некоторые инструменты статического анализа или анализа во время выполнения могут выдать предупреждение.5. @Armfan — Я не запутался — мне совершенно ясно, что IAR в этом отношении соответствует ISO, а GCC — нет. Использование
payload[1]
— это решение, и любые проблемы, которые оно вызывает, вероятно, легче решить, чем недопустимый код , который не будет компилироваться ! Если вы не будете откровенны с проблемами, которые это вызывает, вам больше не смогут помочь. Возможно, следует опубликовать новый вопрос о новой проблеме.