【发布时间】:2013-06-27 16:47:30
【问题描述】:
很久以前,我已经记不清我在 C 中做过多少次这样的事情了:
struct foo f;
struct foo* pf = &f;
char* pc = (char*) pf;
transmit(pc, sizeof(f));
或许:
char* buffer[1024];
receive(buffer, 1024);
float values[256];
for(int ii = 0; ii < 256; ii++) {
float* pf = (float*)(buffer + ii*4);
values[ii] = *pf;
}
或许:
uint32_t ipAddress = ...;
uint8_t* p = (uint8_t*)&ipAddress;
uint8_t octets[4] = {p[0], p[1], p[2], p[3]};
printf("%d.%d.%d.%d\n", octets[0], octets[1], octets[2], octets[3]);
我刚刚发现通过转换为另一种指针类型来重新解释这样的一段内存会调用未定义的行为。然而,上面所有的例子都是绝对必要的。正确的做法是什么?
【问题讨论】:
-
我可以让您对
union关键字感兴趣吗? -
就个人而言,我认为对于这些问题,使用联合是比类型转换更糟糕的解决方案。需要编写更多代码,创建更多奇怪的类型,而您仍然需要到处进行转换。
-
@CarlNorum:如果您的目标类型不是
char,则只需将指针转换为UB;有效的类型规则基本上使 C 成为一种强类型语言,其中类型信息绑定到内存位置本身;然而,类型系统非常不健全,因为编译器会很乐意尝试通过错误类型的表达式访问内存,但实际上可能会假设这些不变量具有更高的优化级别(例如在strict-aliasing的情况下) -
您的示例中“未定义”行为的示例是什么?
-
@CarlNorum:通过联合的类型双关语是完美定义的(只要您读取的成员比您上次写入的成员短,并且您不创建陷阱表示); C99 中甚至有一个脚注告诉你;但是,它在附件中被错误地列为 UB,已用 C11 更正
标签: c pointers memory undefined-behavior