IAR编译器中的指针

lus*_*r00 3 c c++ pointers iar

长话短说我在C中使用IAR EWARM编译器.

uint8_t packet[2048];
uint32_t* src = (uint32_t*)&packet[9];
uint32_t var = *src++;
Run Code Online (Sandbox Code Playgroud)

最后一行导致总线故障.

uint8_t packet[2048];
uint32_t* src = (uint32_t*)&packet[9];
uint32_t var = 0xFE;
*src++;
Run Code Online (Sandbox Code Playgroud)

现在没有公交车故障.我可以在调试器中看到src指向我希望它指向的数据.增量按预期工作但尝试读取它会导致总线故障.

有帮助吗?

M.M*_*M.M 6

&packet[9]可能没有正确对齐uint32_t.在ARM CPU上看到"总线错误"通常是对齐错误的标志.请参阅此处以获得对齐的说明.

在第二个例子中,它可能通过优化*操作来避免总线故障,因为您从不使用结果.

请注意,即使您修复此问题,代码仍会因违反严格别名规则而导致未定义的行为.(uint8_t可能没有别名uint32_t).有些编译器现在可能看起来"正常工作",但代码可能会在将来的任何时候中断.

代码的安全等价物是:

uint8_t *src = &packet[9];
uint32_t var;
memcpy(&var, src, sizeof var);
src += sizeof var;
Run Code Online (Sandbox Code Playgroud)

请注意,如果源数据被指定为具有整数的特定字节顺序(例如,您从网络流获取它而不是先前通过相同方法保存的数据),那么您将需要使用方法来读取数据与...的表示无关uint32_t.(换句话说,"endianness").


Pez*_*ezo 5

可能是您的MCU需要读取32位整数才能与32位对齐.

&packet[9] 绝对不是32位对齐,这就是你出错的原因.