具有结构成员的 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 的相关文章

  • 在实体框架拦截器中向 DbScanExpression 添加内部联接

    我正在尝试使用实体框架 CommandTree 拦截器通过 DbContext 向每个查询添加过滤器 为了简单起见 我有两个表 一个称为 User 有两列 UserId 和 EmailAddress 另一个称为 TenantUser 有两列
  • 在 Xamarin 中隐藏软键盘

    如何隐藏软键盘以便在聚焦时显示Entry在 Xamarin forms 便携式表单项目中 我假设我们必须为此编写特定于平台的渲染器 但以下内容不起作用 我创建自己的条目子类 public class MyExtendedEntry Entr
  • 根据 N 个值中最小的一个返回不同的结果

    不确定如何使标题更具描述性 所以我只是从一个例子开始 我使用下面的代码位 它从枚举中选择一个方向 具体取决于四个轴中哪一个与给定方向相比形成最小角度 static Direction VectorToDirection Vector2 di
  • 类特定的新删除运算符是否必须声明为静态

    标准中是否要求类特定的 new new delete 和 delete 是静态的 我可以让它们成为非静态成员运算符吗 为什么需要它们是静态的 它们被隐式声明为静态 即使您没有键入 static
  • 与 Qt 项目的静态链接

    我有一个在 Visual Studio 2010 Professional 中构建的 Qt 项目 但是 当我运行它 在调试或发布模式下 时 它会要求一些 Qt dll 如果我提供 dll 并将它们放入 System32 中 它就可以工作 但
  • 动态生成的控件 ID 返回为 NULL

    我可以在 Page PreInit 函数中创建动态控件 如何检索控件及其 ID 我的 C 代码用于创建动态控件之一 var btn new WebForms Button btn Text btn ID Addmore btn Click
  • 如何在 QTabWidget Qt 中展开选项卡

    我有一个QTabWidget像这个 但我想展开选项卡以 填充 整个小部件宽度 如下所示 我怎样才能做到这一点 我在用Qt 5 3 2 and Qt 创建者 3 2 1 Update 我尝试使用setExpanding功能 ui gt myT
  • 在 JSQMessagesViewController 中显示 LocationMediaItem

    我刚刚尝试实施LocationMediaItem in my Xamarin iOS应用程序使用JSQMessagesViewController 一切都很顺利 唯一的问题是UICollectionView应该显示位置的单元格永远停留在加载
  • AES 输出是否小于输入?

    我想加密一个字符串并将其嵌入到 URL 中 因此我想确保加密的输出不大于输入 AES 是可行的方法吗 不可能创建任何始终会创建比输入更小的输出的算法 但可以将任何输出反转回输入 如果您允许 不大于输入 那么基本上您只是在谈论同构算法alwa
  • 每个租户的唯一用户名和电子邮件

    我正在使用以下代码编写多租户应用程序ASP NET Core 2 1 我想覆盖默认的与用户创建相关的验证机制 目前我无法创建多个具有相同的用户UserName My ApplicationUser模型有一个名为TenantID 我想要实现的
  • 是否有相当于 Clang/LLVM 的 .spec 文件,在哪里可以找到参考?

    The gcc驱动程序可以配置为使用特定的链接器 特定的选项和其他细节 例如覆盖系统头 specs files 当前 截至撰写本文时 GCC 版本 4 9 0 的手册此处描述了规范文件 https gcc gnu org onlinedoc
  • 如何分析组合的 python 和 c 代码

    我有一个由多个 python 脚本组成的应用程序 其中一些脚本正在调用 C 代码 该应用程序现在的运行速度比以前慢得多 因此我想对其进行分析以查看问题所在 是否有工具 软件包或只是一种分析此类应用程序的方法 有一个工具可以将 python
  • 如何在c的case语句中使用省略号?

    CASE expr no commas ELLIPSIS expr no commas 我在c的语法规则中看到了这样的规则 但是当我尝试重现它时 int test float i switch i case 1 3 printf hi 它失
  • ASP.NET MailMessage.BodyEncoding 和 MailMessage.SubjectEncoding 默认值

    很简单的问题 但我在 MSDN 上找不到答案 查找 ASP NET 将用于的默认值 MailMessage BodyEncoding and MailMessage SubjectEncoding 如果你不在代码中设置它们 Thanks F
  • partitioningBy 必须生成一个包含 true 和 false 条目的映射吗?

    The 分区依据 https docs oracle com javase 8 docs api java util stream Collectors html partitioningBy java util function Pred
  • 更改 Windows Phone 系统托盘颜色

    有没有办法将 Windows Phone 上的系统托盘颜色从黑色更改为白色 我的应用程序有白色背景 所以我希望系统托盘也是白色的 您可以在页面 XAML 中执行此操作
  • C++0x中disable_if在哪里?

    Boost 两者都有enable if and disable if 但 C 0x 似乎缺少后者 为什么它被排除在外 C 0x 中是否有元编程工具允许我构建disable if按照enable if 哦 我刚刚注意到std enable i
  • 使用 QtWebEngine 将 C++ 对象暴露给 Qt 中的 Javascript

    使用 QtWebkit 可以通过以下方式将 C 对象公开给 JavascriptQWebFrame addToJavaScriptWindowObject如中所述https stackoverflow com a 20685002 5959
  • xsi:type 属性搞乱了 C# XML 反序列化

    我使用 XSD exe 根据 XML 架构 xsd 文件 自动生成 C 对象 我正在反序列化 OpenCover 输出 但其中一个部分类未正确生成 这是导致异常的行
  • Java 和/C++ 在多线程方面的差异

    我读过一些提示 多线程实现很大程度上取决于您正在使用的目标操作系统 操作系统最终提供了多线程能力 比如Linux有POSIX标准实现 而windows32有另一种方式 但我想知道编程语言水平的主要不同 C似乎为同步提供了更多选择 例如互斥锁

随机推荐