recvmsg()如何在不违反严格别名的情况下将消息控制到堆栈缓冲区中?

时间:2019-03-17 15:40:41

标签: c posix

在Unix域套接字上传递文件描述符时,使用类型SOL_SOCKET的级别SCM_RIGHTS的控制消息。

使用宏CMSG_FIRSTHDRCMSG_NXTHDRCMSG_DATA读取和写入控制消息。他们考虑到对齐问题。取决于操作系统和libc实现,它们在相同或不同的转换单元中强制转换指针并取消引用结果。它们还会返回此类指针,并且调用代码通常会取消引用它们。

结果,使用简单的堆栈分配的char buf[CMSG_SPACE(sizeof(int))]作为控制消息缓冲区将违反严格的别名,因为只能使用charsigned char类型的左值来访问该缓冲区,unsigned char或其中的限定版本。 (在某些平台上,缓冲区也可能未适当对齐,但是amd64调用约定似乎可以保证这一点,因为缓冲区足够大。)

一个明显正确的解决方法是使用calloc()分配控制消息缓冲区,该缓冲区提供适当对齐的内存而没有有效的类型。但是,我想避免使程序效率降低。

https://svnweb.freebsd.org/base/head/lib/libopenbsd/imsg.c?revision=292023&view=markup中,我找到了另一种方法,其中堆栈缓冲区的类型为union { struct cmsghdr hdr; char buf[CMSG_SPACE(sizeof(int))]; },但是我不知道这是否正确。我认为struct cmsghdr的字段类型为int会有所帮助。

额外的问题:鉴于C ++在(除其他事项外)关于联合的规则不同于C,如何在C ++中做到这一点?

0 个答案:

没有答案