问题:将 2 个指针与灵活的数组成员进行比较是否大于(小于)和相等?
以下是struct inotify_event
在 Linux 中声明的方式:
struct inotify_event {
int wd; /* Watch descriptor */
uint32_t mask; /* Mask describing event */
uint32_t cookie; /* Unique cookie associating related
events (for rename(2)) */
uint32_t len; /* Size of name field */
char name[]; /* Optional null-terminated name */
};
为简单起见省略大小检查,让我们考虑以下代码:
int inotify_fd = inotify_init();
//...
struct inotify_event *ino_buf = malloc(sizeof(inotify_event) * 4096);
read(inotify_fd, ino_buf, sizeof(inotify_event) * 4096));
struct inotify_event *first_event = ino_buf;
struct inotify_event *second_event =
((char *) ino_buf) + sizeof(struct inotify_event) + first_event->len;
if(first_event < second_event){ //UB?
//...
}
我认为指向包含灵活数组成员的结构的指针的比较始终是 UB(即使它们相同)
N2346/6.7.2.1p3
(雇员我的):
具有多个命名成员的结构的最后一个成员可能具有不完整的数组类型;这样的结构(以及可能递归地包含这样的结构的成员的任何联合) 不应是结构的成员或数组的元素。
OTOH,N2346/6.5.8p5
需要比较的指针属于同一个数组:
比较两个指针时,结果取决于所指向对象在地址空间中的相对位置。如果指向对象类型的两个指针都指向同一个对象,或者都指向同一个数组对象的最后一个元素,它们比较相等。如果指向的对象是同一个聚合对象的成员,则指向稍后声明的结构成员的指针比较大于指向结构中较早声明的成员的指针,并且指向具有较大下标值的数组元素的指针比较大于指向同一数组的元素的指针具有较低的下标值。所有指向同一个联合对象成员的指针比较相等。如果表达式 P 指向一个数组对象的一个元素,而表达式 Q 指向同一个数组对象的最后一个元素,指针表达式 Q+1 比较大于 P 。在所有其他情况下,行为是未定义的。
OTOOH,我发现N2346/6.5.8p4
与具有灵活数组成员的结构的定义相矛盾:
出于这些运算符的目的,指向不是数组元素的对象的指针与指向长度为 1 且对象类型作为其元素类型的数组的第一个元素的指针的行为相同。
意思是因为struct inotify_event *first_event
它永远不是数组的元素,N2346/6.7.2.1p3
所以它可以被认为是长度为一的数组的元素,矛盾N2346/6.7.2.1p3