如果 GCC 构建选项带有 -mms-bitfields
,则 epoll_event.data.u64
值可以通过 epoll_wait
截断为 4 字节值>.
我有一个使用 epoll
的套接字服务器的例子,我发现它很奇怪,当我用 -mms-bitfields
构建时,我无法得到原始数据epoll_event.data.u64
中的 8 字节值。我不知道为什么,我可以通过某种方式解决它吗?
代码如下:
...
{
epoll_event ev;
ev.events = EPOLLIN | EPOLLET;
ev.data.u64 = 0x123456789abcdef0;
printf("epoll_ctl add:size=%ld, ptr=%p, u64=%lu\n", sizeof(ev.data.ptr), ev.data.ptr, ev.data.u64);
nRetCode = epoll_ctl(nEpollHandle, EPOLL_CTL_ADD, nSocket, &ev);
printf("epoll_ctl retcode=%d\n", nRetCode);
SOCKET_JMP_ERROR(nRetCode >= 0);
}
// test wait
{
int nRetCount = 0;
int nRemainEventCount = 1;
epoll_event EpollEvent;
epoll_event * pEpollEvent = &EpollEvent;
nRetCount = epoll_wait(nEpollHandle, pEpollEvent, nRemainEventCount, 0);
printf("epoll_wait nRetCount=%d\n", nRetCount);
SOCKET_JMP_ERROR(nRetCount >= 0);
printf("epoll_wait wait:size=%ld, ptr=%p, u64=%lu\n", sizeof((pEpollEvent->data).ptr), (pEpollEvent->data).ptr, (pEpollEvent->data).u64);
}
...
并且在没有-mms-bitfields
的情况下构建,输出消息是这样的:
epoll_ctl add:size=8, ptr=0x123456789abcdef0, u64=1311768467463790320
epoll_ctl retcode=0
epoll_wait nRetCount=1
epoll_wait wait:size=8, ptr=0x123456789abcdef0, u64=1311768467463790320
如果构建选项带有 -mms-bitfields
,则消息为:
epoll_ctl add:size=8, ptr=0x123456789abcdef0, u64=1311768467463790320
epoll_ctl retcode=0
epoll_wait nRetCount=1
epoll_wait wait:size=8, ptr=0x9abcdef0, u64=2596069104
这是 gcc -v
的 GCC 版本:
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/x86_64-linux/4.8.5/lto-wrapper
Target: x86_64-linux
Configured with: ../configure -build=x86_64-linux -enable-checking=release -enable-languages=c,c++ -disable-multilib --with-gmp --with-mpfr --with-mpc
Thread model: posix
gcc version 4.8.5 (GCC)
那么操作系统是CentOS 6.5
:
Linux version 2.6.32-431.el6.x86_64 (mockbuild@c6b8.bsys.dev.centos.org) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) ) #1 SMP Fri Nov 22 03:15:09 UTC 2013
有人可以解释一下这个问题吗?谢谢....
最佳答案
-mms-bitfields
改变了结构的布局方式,在某些情况下可能导致系统 header 中定义的结构与您的系统库 ABI 不兼容。这很可能是使用 -mms-bitfields
时 epoll
行为不正确的原因。
如果编译 32 位代码,您可以使用 __attribute__((ms_struct))
将 MS 结构布局应用于单个结构,这可能是最好的前进方式,例如:
#include <stdio.h>
struct a
{
short a :16;
int : 0;
short b :16;
} __attribute__((ms_struct)) aa;
int main()
{
printf("sizeof struct a = %d\n", (int)sizeof(struct a));
printf("sizeof aa = %d\n", (int)sizeof(aa));
return 0;
}
这打印:
sizeof struct a = 8
sizeof aa = 8
如果没有 __attribute__((ms_struct))
(也没有 -mms-bitfields
),它会报告大小为 6。
关于c++ - 如果 GCC 构建选项带有 '-mms-bitfields' ,则 'epoll_event.data.u64' 值可以通过 'epoll_wait' 截断为 4 字节值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52442141/