如果GCC build选项带有-mms-bitfields,则可以通过epoll_event.data.u64epoll_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的build选项,则消息为:
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更改了结构的布局方式,并且在某些情况下可能会导致系统头文件中定义的结构与系统库ABI不兼容。这很可能是使用epoll-mms-bitfields行为不正确的原因。

如果编译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 build选项带有 '-mms-bitfields',则可以通过 'epoll_event.data.u64'将 'epoll_wait'值截断为4个字节的值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52442141/

10-12 16:36