用结构数据减去指针
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);
我发现了一些遗留代码并认为它在减去指针方面有 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);