将 uint64_t 转换为字节时从不同大小的整数转换为指针

cast to pointer from integer of different size when converting uint64_t to bytes

[编辑]我想以网络字节顺序将 uint64_t 写入 char* 数组,以使用 sendto 将其作为 UDP 数据报发送,uint64_t 有 8 个字节,因此我将它们转换如下:

void strcat_number(uint64_t v, char* datagram) {
    uint64_t net_order = htobe64(v);
        for (uint8_t i=0; i<8 ;++i) {
    strcat(datagram, (const char*)((uint8_t*)&net_order)[i]);
    }
}

wchich给我

警告:从不同大小的整数转换为指针 [-Wint-to-pointer-xast] strcat(数据报, (const char*)((uint8_t*)&net_order)[i]);

我怎样才能摆脱这个警告,或者让这个数字转换更简单或更清晰?

((uint8_t*)&net_order)

这是一个指向 net_order 的指针,被转换为 uint8_t 指针

((uint8_t*)&net_order)[i]

这是 net_order 的底层表示的第 i 个字节。

(const char*)((uint8_t*)&net_order)[i]

这和上面一样,但是粗暴地转换成了const char *。这是一个无效的指针,这是编译器警告你的;即使只是创建这个指针也是未定义的行为,以任何方式使用它几乎肯定会导致崩溃。

请注意,即使您以某种方式设法让这个杂乱无章的工作,strcat 仍然是错误的函数,因为它处理以 NUL 结尾的字符串,而在这里您试图将二进制数据放入您的缓冲区和二进制数据自然可以包含嵌入的 NUL。 strcat 将在第一个 NUL 处附加(并在第二个参数中的第一个 NUL 处停止)而不是 "real" 末尾。

如果您要构建二进制数据缓冲区,则必须直接使用 memcpy,最重要的是,您不能使用依赖于最终 NUL 的字符串相关函数来了解字符串的结束位置,但您必须明确跟踪您使用了多少字节(即数据报中的当前位置)。