You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Linux下C++结构体扩展时的柔性数组非末尾成员错误

问题:Linux进程变更检测结构体编译错误及优化方案咨询

背景

我曾使用如下结构体处理Linux进程变更检测:

struct __attribute__((aligned(NLMSG_ALIGNTO))) event_message {
    nlmsghdr f_nl_hdr;
    struct __attribute__((__packed__)) {
        cn_msg f_cn_msg;
        proc_event f_proc_ev;
    } f_nl_msg;
};

编译错误

升级至Ubuntu 23.04的g++12.2.0后,触发编译错误:

/usr/include/linux/connector.h: In member function ‘void ed::process_changed::listen_for_events()’:  
/usr/include/linux/connector.h:78:14: error: flexible array member ‘cn_msg::data’ not at end of ‘struct ed::process_changed::listen_for_events()::multicast_message’  
  78 |         __u8 data[];  
     |              ^~~~

错误原因是cn_msg中的柔性数组成员data[]并非所在嵌套结构体的最后成员,旧编译器可正常编译,但新编译器直接报错;且我开启了-Werror将警告视为错误,无法通过#pragma忽略该错误。

已尝试的解决方案

我想到通过手动分配内存并强制转换的方式规避问题,步骤如下:

  1. 计算所需总内存大小:
constexpr std::size_t size(sizeof(nlmsghdr) + sizeof(cn_msg) + sizeof(proc_event));
  1. 创建字节缓冲区:
std::vector<std::uint8_t> buffer(size);
  1. 将缓冲区转换为对应结构体指针:
nlmsghdr * header = reinterpret_cast<nlmsghdr *>(buffer.data());
cn_msg * msg = reinterpret_cast<cn_msg *>(header + 1);
proc_event * event = reinterpret_cast<proc_event *>(msg + 1);

*注:查阅reinterpret_cast文档后,我认为该操作不属于未定义行为,前提是各结构体的对齐要求一致,且缓冲区对应位置的字节符合目标结构体格式。

但此方案代码繁琐且容易出错,希望找到更简洁可靠的替代方案。

约束条件

  • 必须使用/usr/include下的系统头文件定义,不能自行重定义结构体,以适配当前系统版本
  • 代码仅需支持Ubuntu平台下的g++编译,无需考虑其他平台兼容性

内容的提问来源于stack exchange,提问作者Alexis Wilke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 12:53:28