比较 2 个指向具有灵活数组成员的结构的指针
Comparing 2 pointers to a struct with a flexible array member
问题: 将 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
(我的公司):
the last member of a structure with more than one named member may
have incomplete array type; such a structure (and any union
containing, possibly recursively, a member that is such a structure)
shall not be a member of a structure or an element of an array.
OTOH,N2346/6.5.8p5
需要比较指针以属于同一数组:
When two pointers are compared, the result depends on the relative
locations in the address space of the objects pointed to. If two
pointers to object types both point to the same object, or both point
one past the last element of the same array object, they compare
equal. If the objects pointed to are members of the same aggregate
object, pointers to structure members declared later compare greater
than pointers to members declared earlier in the structure, and
pointers to array elements with larger subscript values compare
greater than pointers to elements of the same array with lower
subscript values. All pointers to members of the same union object
compare equal. If the expression P points to an element of an array
object and the expression Q points to the last element of the same
array object, the pointer expression Q+1 compares greater than P . In
all other cases, the behavior is undefined.
OTOOH,我发现 N2346/6.5.8p4
与具有灵活数组成员的结构的定义相矛盾:
For the purposes of these operators, a pointer to an object that is
not an element of an array behaves the same as a pointer to the first
element of an array of length one with the type of the object as its
element type.
意思是因为struct inotify_event *first_event
从来不是N2346/6.7.2.1p3
数组的元素所以它可以被认为是长度为1的数组的元素,与N2346/6.7.2.1p3
[=22相矛盾=]
如果 T
是一个包含灵活数组成员的结构,则不能声明 T[intVal]
形式的对象或类型;这是一个编译时约束,要求编译器在程序试图声明这样的数组时发出诊断。
标准的一个单独部分规定,指向类型 T
对象的指针的行为与指向类型 T[1]
对象的指针的行为相同。我不认为有任何意图将具有灵活数组成员的结构从该条款中排除在合理适用的情况下。尝试声明类型 T[1]
的对象或 typedef 将违反约束,需要进行诊断,并且不可能有两个不匹配的 T
类型的指针相同的数组,但没有理由不对指向相同类型 T
的两个指针之间的关系比较进行质量实现,因为它们将对指向同一数组的相同元素的两个指针之间进行比较。
问题: 将 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
(我的公司):
the last member of a structure with more than one named member may have incomplete array type; such a structure (and any union containing, possibly recursively, a member that is such a structure) shall not be a member of a structure or an element of an array.
OTOH,N2346/6.5.8p5
需要比较指针以属于同一数组:
When two pointers are compared, the result depends on the relative locations in the address space of the objects pointed to. If two pointers to object types both point to the same object, or both point one past the last element of the same array object, they compare equal. If the objects pointed to are members of the same aggregate object, pointers to structure members declared later compare greater than pointers to members declared earlier in the structure, and pointers to array elements with larger subscript values compare greater than pointers to elements of the same array with lower subscript values. All pointers to members of the same union object compare equal. If the expression P points to an element of an array object and the expression Q points to the last element of the same array object, the pointer expression Q+1 compares greater than P . In all other cases, the behavior is undefined.
OTOOH,我发现 N2346/6.5.8p4
与具有灵活数组成员的结构的定义相矛盾:
For the purposes of these operators, a pointer to an object that is not an element of an array behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.
意思是因为struct inotify_event *first_event
从来不是N2346/6.7.2.1p3
数组的元素所以它可以被认为是长度为1的数组的元素,与N2346/6.7.2.1p3
[=22相矛盾=]
如果 T
是一个包含灵活数组成员的结构,则不能声明 T[intVal]
形式的对象或类型;这是一个编译时约束,要求编译器在程序试图声明这样的数组时发出诊断。
标准的一个单独部分规定,指向类型 T
对象的指针的行为与指向类型 T[1]
对象的指针的行为相同。我不认为有任何意图将具有灵活数组成员的结构从该条款中排除在合理适用的情况下。尝试声明类型 T[1]
的对象或 typedef 将违反约束,需要进行诊断,并且不可能有两个不匹配的 T
类型的指针相同的数组,但没有理由不对指向相同类型 T
的两个指针之间的关系比较进行质量实现,因为它们将对指向同一数组的相同元素的两个指针之间进行比较。