c++ - 如果 GCC 构建选项带有 '-mms-bitfields' ,则 'epoll_event.data.u64' 值可以通过 'epoll_wait' 截断为 4 字节值

标签 c++ gcc centos6 epoll

如果 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-bitfieldsepoll 行为不正确的原因。

如果编译 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/

相关文章:

php - 在 CentOs 上安装 php-ldap

c++ - WebRTC 音频处理模块 (APM) 和计算播放设备的回声延迟

c++ - 从 const void * 转换为 float 数组

c# - Google Protocol Buffers - 固定大小的缓冲区?

c - 导入unistd.h后,编译器声明sbrk()是隐式声明。为什么是这样?

linux - uWSGI --chmod-socket 不工作

FFmpeg 命令仅适用于 root (centos 6.10)

c++ - Linux 中最好的 C++ 开发环境

c - 编译时出现多个相同错误 "error: expected ' )' before ' *' token

gcc - 弱符号和 dlopen() 与 clang 与 gcc