【发布时间】:2016-08-17 10:06:22
【问题描述】:
我正在修复一些不是我写的代码,所以我发现了这个:
#define get_u_int16_t(X,O) (*(u_int16_t *)(((u_int8_t *)X) + O))
如果违反了规则,我该如何更改它以保持规则?
宏是这样调用的:
if(get_u_int16_t(packet->payload, i) == ...) { ... }
其中 payload 是 const unsigned char *,i 是 unsigned int 。
情况是:
struct orig {
[...]
struct pkt packet;
}*;
struct pkt {
[...]
const u_int8_t *payload;
}*;
这样调用:
struct orig * flow;
struct pkt * packet = &flow->packet;
有效载荷是一个字符串
i 以 0 的值开头,它位于有效载荷长度的循环 for 内(u_int16_t len):
for(i = 0; i < len; i++) {
if(get_u_int16_t(packet->payload, a) == /*value*/) {
// do stuff
}
【问题讨论】:
-
从您显示的代码中无法确定。出示 SSCCE。
-
这是否违反严格的别名规则取决于为
X传递的参数类型。如果参数是u_int16_t*类型并且指向一个有效类型为u_int16_t的对象,并且它的值可以转换为u_int8_t*(u_int8_t没有比u_int16_t更严格的对齐要求),行为是好的-定义。 -
我也在这里问过,所以这就是我打开这个问题的原因,只是想更好地思考plus.google.com/u/0/+MicheleCampus/posts/YjUFgDQbDy8?cfem=1
-
我将修改添加一段代码的示例。
-
即使您最近添加了内容,仍然不足以提供明确的答案。
packet->payload的类型是const unsigned char *,当然,但它实际上指向的是什么类型的对象? (暂时忘记整个指针转换问题,因为大多数编译器将指针类型转换视为返回指向同一对象的指针)。更具体地说:packet->payload指向的对象的有效类型(根据 6.5p7)是什么?
标签: c macros strict-aliasing type-punning