C++11可变大小POD结构

C++11 variable size POD struct

本文关键字:POD 结构 C++11      更新时间:2023-10-16

我正在C++11中编写一个低lewel数据操作代码,我想在结构的末尾使用一个已知的灵活数组的C特性(请参阅此处的一些信息(。

struct variableCell
{
    /**
     * @brief Size in bytes of following data.
     */
    std::uint32_t cellSize;
    /**
     * @brief Data stored in overlay.
     */
    std::uint8_t cellData[];
};

一旦我使用GCC与参数

-Wall -pedantic -std=c++11

我得到了这个警告

xxx.h:xx: warning: ISO C++ forbids zero-size array 'variableCell' [-Wpedantic]

这曾经是一个完全正确的特征。请不要告诉我我的方法是错误的——这是并且一直是低级别数据操作的正确方法。

为什么标准改变了这一点,以及如何禁用这一特定警告?

感谢

编辑:很抱歉,我弄错了纯C功能,这是C++不包含的例外之一。我会考虑采用不同的方法。但只是出于我的好奇,哪些编译器允许将其作为非标准扩展,以及如何让他们在没有警告的情况下接受它?

感谢

作为参考灵活数组成员部分中ISO C和ISO C++状态之间的不兼容:

C++不支持灵活的数组成员。

(一些C++编译器可能会将此功能作为扩展提供,但可能仅对POD结构类型有效。(

gcc确实支持将其作为clang的扩展。显然,这在Visual Studio中也适用——如果你不使用/Za,我可以在上面找到任何文档,除了Stephan t.Lavavej的这篇文章。

我不认为有一种可移植的方法可以让警告静音,但像源代码中gcc中的部分禁用迂腐警告之类的东西应该适用于gcc

您可以用c++和一个新的自定义操作符来模拟它

struct VariableCell {
    VariableCell( std::uint32_t sz ) : cellSize(sz) {}
    std::uint8_t* data() { return reinterpret_cast<std::uint8_t*>(this+1); }
    static void* operator new(std::size_t sz, std::uint32_t dataSz) {
        return ::operator new(sz+dataSz);
    }
private:
    std::uint32_t cellSize;
};
std::unique_ptr<VariableCell> CreateVariableCell( std::uint32_t size ) {
    return std::unique_ptr<VariableCell>{ new (size) VariableCell{size} };
}

您必须检查哪些标准,C++11仍然不允许0长度数组(§8.3.4/1(,以及C99(§6.7.5.2/1(。看起来它们只是一个C功能,但我宁愿说是一个旧的C破解。你确定找不到更好的解决方案吗?