相关疑难解决方法(0)

什么是严格别名规则?

当询问C中常见的未定义行为时,灵魂比我提到的严格别名规则更加开明.
他们在说什么?

c strict-aliasing undefined-behavior type-punning

778
推荐指数
10
解决办法
19万
查看次数

将缓冲区解释为结构的正确,可移植的方法

我的问题的背景是网络编程.假设我想通过网络在两个程序之间发送消息.为简单起见,假设消息看起来像这样,字节顺序不是问题.我想找到一种正确,可移植且有效的方法来将这些消息定义为C结构.我知道有四种方法:显式铸造,通过联合铸造,复制和编组.

struct message {
    uint16_t logical_id;
    uint16_t command;
};
Run Code Online (Sandbox Code Playgroud)

显式铸造:

void send_message(struct message *msg) {
    uint8_t *bytes = (uint8_t *) msg;
    /* call to write/send/sendto here */
}

void receive_message(uint8_t *bytes, size_t len) {
    assert(len >= sizeof(struct message);
    struct message *msg = (struct message*) bytes;
    /* And now use the message */
    if (msg->command == SELF_DESTRUCT)
        /* ... */
}
Run Code Online (Sandbox Code Playgroud)

我的理解是send_message不违反别名规则,因为byte/char指针可以为任何类型设置别名.但是,相反的情况并非如此,因此receive_message违反了别名规则,因此具有未定义的行为.

通过联盟投射:

union message_u {
    struct message m;
    uint8_t bytes[sizeof(struct message)];
};

void receive_message_union(uint8_t *bytes, size_t …
Run Code Online (Sandbox Code Playgroud)

c networking portability strict-aliasing

24
推荐指数
2
解决办法
9395
查看次数

Linux中的结构分配在ARM中失败但在x86中成功

我注意到一些非常奇怪的东西.说我已经定义了以下结构

typedef struct
{
  uint32_t a;
  uint16_t b;
  uint32_t c;
} foo;
Run Code Online (Sandbox Code Playgroud)

这个结构包含在我从网络接收的大缓冲区中.

以下代码适用于x86,但我SIGBUS在ARM上收到.

extern void * buffer;
foo my_foo;
my_foo = (( foo * ) buffer)[0];
Run Code Online (Sandbox Code Playgroud)

用memcpy替换解除引用的指针解决了这个问题.

在ARM中搜索SIGBUS时,我发现这与内存对齐somwhow有关.

有人可以解释发生了什么吗?

c linux arm memory-alignment sigbus

3
推荐指数
1
解决办法
1556
查看次数