用结构数据减去指针

Subtracting pointers with structure data

我发现了一些遗留代码并认为它​​在减去指针方面有 UB。 如果我是对的并且 UB 在这里 - 我可以通过 ASAN 找到它吗? 我尝试选项 -fsanitize=address,pointer-subtract,但没有发现问题。

g++ -O0 -fsanitize=address,pointer-subtract main.c
ASAN_OPTIONS=detect_invalid_pointer_pairs=1 ./a.out

或者我弄错了没有UB?

#define ATTRIBUTE_PACKED_1 __attribute__((aligned(1),packed))
typedef struct DAT
{
    unsigned int IP;
    unsigned short port;
} ATTRIBUTE_PACKED_1 Data;

int main(void)
{
    static Data data;
    int diff = ((unsigned char*) &data) - ((unsigned char*) &data.port);

return 0;
}

没有与指针相关的未定义行为。您可以转换指针,也可以减去指针,只要它们指向同一个对象(因为一个对象可以被视为 char 的数组)。

请注意,这可以替换为 offsetof 宏并对结果取反。

但是,存在与名称相关的未定义行为 - 以 _(下划线)开头后跟大写字母的名称保留用于实现(在任何范围内)。

将指针转换为 unsigned char* 以访问原始字节,并将指针转换为在对象或对象数组(在本例中,data 中执行指针运算)可以被视为 1 个 Data 对象的数组),是 C 和 C++ 标准中明确定义的行为。

然而,port的地址在内存中位于data的地址之后,所以你的减法将导致负偏移量,这可能是也可能不是你要找的.要在 data 内获得 port 的字节偏移量,您需要以相反的顺序减去地址:

int offset = ((unsigned char*) &data.port) - ((unsigned char*) &data);