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

recvmsg()如何在不违反严格别名的情况下将消息控制到堆栈缓冲区中?,c,posix,C,Posix,通过Unix域套接字传递文件描述符时,将使用类型为SCM\u RIGHTS的SOL\u SOCKET级别的控制消息 使用宏CMSG\u FIRSTHDR、CMSG\u NXTHDR和CMSG\u DATA读取和写入控制消息。它们考虑了对齐问题。根据操作系统和libc实现的不同,它们在相同或不同的转换单元中强制转换指针并取消对结果的引用。它们还返回这样的指针,调用代码通常会取消对它们的引用 因此,使用分配的简单堆栈char buf[CMSG_SPACE(sizeof(int))]作为控制消息缓冲区

通过Unix域套接字传递文件描述符时,将使用类型为
SCM\u RIGHTS
SOL\u SOCKET
级别的控制消息

使用宏
CMSG\u FIRSTHDR
CMSG\u NXTHDR
CMSG\u DATA
读取和写入控制消息。它们考虑了对齐问题。根据操作系统和libc实现的不同,它们在相同或不同的转换单元中强制转换指针并取消对结果的引用。它们还返回这样的指针,调用代码通常会取消对它们的引用

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

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

在中,我发现了一种不同的方法,其中堆栈缓冲区的类型为
union{struct cmsghdr hdr;char buf[CMSG_SPACE(sizeof(int));}
,但我不知道这是否正确。我想
struct cmsghdr
有一个类型为
int
的字段会有所帮助


额外的问题:如何在C++中这样做,因为C++与(c)< /p>相比有不同的规则(除了其他东西)。我怀疑POSIX需要C实现来对齐结构,这样就不会有问题。@ Barmar。甚至像这样的文档也假设它是由实现提供的(或不是…)。并使用相同的

union
构造来强制进行问题中提到的正确对齐。(续)注意,还有相当多的讨论涉及到