gpt4 book ai didi

c - read(2)ing 结构时如何正确避免 "cast increases required alignment"警告?

转载 作者:行者123 更新时间:2023-11-30 19:29:49 31 4
gpt4 key购买 nike

很多 Linux 内核接口(interface)(inotify 等)都是通过 read(2) 工作的。从某个文件描述符以结构体的形式获取数据。执行此操作的代码通常如下所示:

#include <unistd.h>
#include <sys/inotify.h>

int main() {
// all error checking omitted for brevity
int inotify_fd = inotify_init();
inotify_add_watch(inotify_fd, "file_to_watch", IN_ALL_EVENTS);
char c[4096];
for(;;) {
ssize_t len = read(inotify_fd, c, sizeof(c));
struct inotify_event *s;
for(char* p = c; p < c + len; p += sizeof(struct inotify_event) + s->len) {
s = (struct inotify_event *)p;
// do stuff with s
}
}
}

当我用 clang 编译上述内容时,我收到此警告:

inotify.c:13:15: warning: cast from 'char *' to 'struct inotify_event *' increases required alignment from 1 to 4 [-Wcast-align]
s = (struct inotify_event *)p;
^~~~~~~~~~~~~~~~~~~~~~~~~

我修复此警告的第一次尝试是修复对齐方式:我尝试使用 #include <stdalign.h>alignas(struct inotify_event) ,无济于事。

我想真正修复这个警告,而不仅仅是让它静音。我怎样才能这样做?

编辑:这是 inotify fd 上的 read(2) 的工作原理,如 its man page 所记录。 :

Each successful read(2) returns a buffer containing one or more of the following structures:

       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 */
};

[...]

This filename is null-terminated, and may include further null bytes ('\0') to align subsequent reads to a suitable address boundary.

The len field counts all of the bytes in name, including the null bytes; the length of each inotify_event structure is thus sizeof(struct inotify_event)+len.

The behavior when the buffer given to read(2) is too small to return information about the next event depends on the kernel version: in kernels before 2.6.21, read(2) returns 0; since kernel 2.6.21, read(2) fails with the error EINVAL. Specifying a buffer of size

sizeof(struct inotify_event) + NAME_MAX + 1

will be sufficient to read at least one event.

我无法读取部分结构,例如与固定大小的片段分开读取名称。如果我没有指定足够大的缓冲区来读取整个结构,我就不会得到任何内容。

最佳答案

union {
char buf[1];
struct some_struct mine;
} b;

确保b.buf和b.mine具有相同的地址;此外,编译器保证任何所需的对齐。几乎不需要属性扩展(例如,alignas),并且使源代码摆脱这些繁琐的内容具有很大的值(value)。

关于c - read(2)ing 结构时如何正确避免 "cast increases required alignment"警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52349894/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com