具有结构成员的 C++ 联合结构适用于 Clang 和 MSVC,但不适用于 GCC

2024-02-21

我试图定义一个联合结构,其中一些结构和原始成员在内存中与一个简单的数组重叠。这在 Clang 和 MSVC 中完美运行,但不能用 GCC (G++) 编译。

struct Vector3 {
    float x;
    float y;
    float z;
    Vector3() {}
};

struct Plane {
    union {
        struct {
            Vector3 normal;
            float d;
        };
        float elements[4] = { 0 };
    };
    Plane() {}
};

使用 GCC,我收到以下编译错误:

<source>:11:33: error: member 'Vector3 Plane::<unnamed union>::<unnamed struct>::normal' with constructor not allowed in anonymous aggregate
   11 |                         Vector3 normal;
      |                                 ^~~~~~

我给出的代码示例是有效的 C++ 吗?为什么在匿名聚合中不允许使用它,但在命名聚合中却似乎可以工作?我可以对其进行哪些更改以使其在 GCC 中工作,而不涉及删除构造函数或在联合中命名结构?它在 Clang 和 MSVC 中有效但在 GCC 中无效的原因是什么?

如果我更换的话有办法让它工作吗struct { with struct Named {?


我给出的代码示例是有效的 C++ 吗?

不可以。不允许使用匿名结构,因此该程序格式不正确。

它在 Clang 和 MSVC 中工作的原因是什么

当一个格式错误的程序运行时,通常是由于语言扩展造成的。

但不在海湾合作委员会

也许类似语言扩展的实现存在差异。当然,这种扩展的限制不是由语言定义的。由于此扩展基于 C 语言功能,因此它不一定适用于构造函数等 C++ 功能,这是有道理的。

我可以对其进行哪些更改以使其在 GCC 中工作,而不涉及删除构造函数或在联合中命名结构?

使程序明确定义 C++ 的唯一方法是不使用匿名结构。


额外答案:如果您希望阅读elements写信给之后normal or d反之亦然,那么这也是不允许的。程序的行为是未定义的。


如何使用重叠内存创建不同名称的属性?除了 Plane 之外,我还想在其他结构中执行此操作,例如通过 3D Basis 结构 columns[3] ,其中数组的成员也可通过 x、y 和 z 访问。

C++在这方面有局限性,不能用简单的方法来完成。可以通过依赖运算符重载来完成,但有点复杂:

template<class T, std::size_t size, std::size_t i>
struct Pun {
    T a[size];
    static_assert(i < size);
    auto& operator=(T f) { a[i] = f; return *this; }
    operator       T&()        &   { return a[i]; }
    operator const T&()  const &   { return a[i]; }
    operator       T ()        &&  { return a[i]; }
    T      * operator&()       &   { return a+i ; }
    T const* operator&() const &   { return a+i ; }
};

template<class T, std::size_t size>
struct Pun<T, size, size> {
    T a[size];
    using A = T[size];
    operator       A&()        &   { return a; }
    operator const A&()  const &   { return a; }
    A      * operator&()       &   { return &a; }
    A const* operator&() const &   { return &a; }
};

union Plane {
    Pun<float, 4, 4> elements;
    Pun<float, 4, 0> x;
    Pun<float, 4, 1> y;
    Pun<float, 4, 2> z;
    Pun<float, 4, 3> d;
};

读取不活跃成员Plane是允许的,因为所有元素都是布局兼容的结构。x等可以隐式转换为 float 和elements可以隐式转换为 float 数组。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

具有结构成员的 C++ 联合结构适用于 Clang 和 MSVC,但不适用于 GCC 的相关文章

  • WPF DataGrid 多选

    我读过几篇关于这个主题的文章 但很多都是来自 VS 或框架的早期版本 我想做的是从 dataGrid 中选择多行并将这些行返回到绑定的可观察集合中 我尝试创建一个属性 类型 并将其添加到可观察集合中 它适用于单个记录 但代码永远不会触发多个
  • 在 xaml 中编写嵌套类型时出现设计时错误

    我创建了一个用户控件 它接受枚举类型并将该枚举的值分配给该用户控件中的 ComboBox 控件 很简单 我在数据模板中使用此用户控件 当出现嵌套类型时 问题就来了 我使用这个符号来指定 EnumType x Type myNamespace
  • C# 异步等待澄清?

    我读了here http blog stephencleary com 2012 02 async and await html that 等待检查等待的看看它是否有already完全的 如果 可等待已经完成 那么该方法将继续 运行 同步
  • 机器Epsilon精度差异

    我正在尝试计算 C 中双精度数和浮点数的机器 epsilon 值 作为学校作业的一部分 我在 Windows 7 64 位中使用 Cygwin 代码如下 include
  • 随着时间的推移,添加到 List 变得非常慢

    我正在解析一个大约有 1000 行的 html 表 我从一个字符串中添加 10 个字符串 td 每行到一个list td
  • 传递给函数时多维数组的指针类型是什么? [复制]

    这个问题在这里已经有答案了 我在大学课堂上学习了 C 语言和指针 除了多维数组和指针之间的相似性之外 我认为我已经很好地掌握了这个概念 我认为由于所有数组 甚至多维 都存储在连续内存中 因此您可以安全地将其转换为int 假设给定的数组是in
  • 如何从本机 C(++) DLL 调用 .NET (C#) 代码?

    我有一个 C app exe 和一个 C my dll my dll NET 项目链接到本机 C DLL mynat dll 外部 C DLL 接口 并且从 C 调用 C DLL 可以正常工作 通过使用 DllImport mynat dl
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • 如何获取 EF 中与组合(键/值)列表匹配的记录?

    我有一个数据库表 其中包含每个用户 年份组合的记录 如何使用 EF 和用户 ID 年份组合列表从数据库获取数据 组合示例 UserId Year 1 2015 1 2016 1 2018 12 2016 12 2019 3 2015 91
  • 两个类可以使用 C++ 互相查看吗?

    所以我有一个 A 类 我想在其中调用一些 B 类函数 所以我包括 b h 但是 在 B 类中 我想调用 A 类函数 如果我包含 a h 它最终会陷入无限循环 对吗 我能做什么呢 仅将成员函数声明放在头文件 h 中 并将成员函数定义放在实现文
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 如何在当前 Visual Studio 主机内的 Visual Studio 扩展中调试使用 Roslyn 编译的代码?

    我有一个 Visual Studio 扩展 它使用 Roslyn 获取当前打开的解决方案中的项目 编译它并从中运行方法 程序员可以修改该项目 我已从当前 VisualStudioWorkspace 成功编译了 Visual Studio 扩
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲
  • 如何确定 CultureInfo 实例是否支持拉丁字符

    是否可以确定是否CultureInfo http msdn microsoft com en us library system globalization cultureinfo aspx我正在使用的实例是否基于拉丁字符集 我相信你可以使

随机推荐