- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我的印象是访问除最后一组之外的 union
成员是 UB,但我似乎找不到可靠的引用(除了声称它是 UB 但没有任何来自标准的支持)。
那么,这是未定义的行为吗?
最佳答案
令人困惑的是,C 明确允许通过 union 进行类型双关,而 C++ ( c++11 ) 没有这样的权限。
6.5.2.3 Structure and union members
95) If the member used to read the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called ‘‘type punning’’). This might be a trap representation.
C++的情况:
9.5 Unions [class.union]
In a union, at most one of the non-static data members can be active at any time, that is, the value of at most one of the non-static data members can be stored in a union at any time.
后来的 C++ 语言允许使用包含 struct
和公共(public)初始序列的 union ;但是,这不允许类型双关。
要确定在 C++ 中是否允许 union 类型双关 ,我们必须进一步搜索。回想一下 c99是 C++11 的规范性引用(并且 C99 与 C11 具有相似的语言,允许 union 类型双关):
3.9 Types [basic.types]
4 - The object representation of an object of type T is the sequence of N unsigned char objects taken up by the object of type T, where N equals sizeof(T). The value representation of an object is the set of bits that hold the value of type T. For trivially copyable types, the value representation is a set of bits in the object representation that determines a value, which is one discrete element of an implementation-defined set of values. 42
42) The intent is that the memory model of C++ is compatible with that of ISO/IEC 9899 Programming Language C.
当我们阅读时会变得特别有趣
3.8 Object lifetime [basic.life]
The lifetime of an object of type T begins when: — storage with the proper alignment and size for type T is obtained, and — if the object has non-trivial initialization, its initialization is complete.
因此,对于包含在 union 中的原始类型(ipso facto 具有微不足道的初始化),对象的生命周期至少包含 union 本身的生命周期。这允许我们调用
3.9.2 Compound types [basic.compound]
If an object of type T is located at an address A, a pointer of type cv T* whose value is the address A is said to point to that object, regardless of how the value was obtained.
假设我们感兴趣的操作是类型双关语,即获取非事件 union 成员的值,并且根据上述给出我们对该成员引用的对象的有效引用,那么该操作是左值到右值的转换:
4.1 Lvalue-to-rvalue conversion [conv.lval]
A glvalue of a non-function, non-array type
T
can be converted to a prvalue. IfT
is an incomplete type, a program that necessitates this conversion is ill-formed. If the object to which the glvalue refers is not an object of typeT
and is not an object of a type derived fromT
, or if the object is uninitialized, a program that necessitates this conversion has undefined behavior.
接下来的问题是,作为非事件 union 成员的对象是否通过存储初始化到事件 union 成员。据我所知,情况并非如此,尽管如果:
char
数组存储并返回 (3.9:2),或者非事件成员对 union 的访问已定义并被定义为遵循对象和值表示,没有上述插入之一的访问是未定义的行为。这对允许在此类程序上执行的优化有影响,因为实现当然可能假设未发生未定义的行为。
也就是说,尽管我们可以合法地为非事件的 union 成员形成一个左值(这就是为什么在没有构造的情况下分配给非事件成员是可以的),但它被认为是未初始化的。
关于c++ - 访问不活动的 union 成员和未定义的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11373203/
自从我的问题here无法自信地回答,我在这里再次询问,希望有人确切知道: 指向 union 的指针和包含指向其元素的指针的 union 之间有什么区别(除了语法之外)吗? this中生成的程序集示例是
在 C 语言中,是否可以在另一个 union 体中定义一个 union 体?如果不是,为什么不可能?或者如果可以,可以在哪里使用? 最佳答案 假设您要定义: union myun { int x;
在 C 中,是否可以在另一个 union 中定义一个 union ?如果不是,为什么不可能?或者如果是,它可以在哪里使用? 最佳答案 假设你想定义: union myun { int x; s
我正在阅读一些代码并发现如下内容: typedef union { int int32; int boolean; time_t date; char *string;
我正在学习Lua,我更愿意使用冒号(:)作为方法。不幸的是,它并非在所有地方都有效。看我的代码: 设置= {} 本地mt = {} 函数Set:new(m) 本地集= {} setmetatable(
我遇到了一些性能问题,我有如下查询: SELECT * FROM Foo UNION SELECT * FROM Boo UNION SELECT * FROM Koo 我确信 Koo 不会返回任何重
This question already has answers here: C++ Structure Initialization (16个答案) 上个月关闭。 我正在尝试将一些用于嵌入式目标的
UNION 和 UNION ALL 有什么区别? 最佳答案 UNION 删除重复记录(结果中的所有列都相同),UNION ALL 则不会。 使用 UNION 而不是 UNION ALL 时会影响性能,
我想在两个表上使用联合运算符。我希望结果集消除由联合创建的重复值,但不消除表中预先存在的重复值。考虑这段代码... select b from (values (1), (2), (2
我知道 UNION 会删除重复项,但即使没有重复项也会更改结果顺序。 我有两个 select 语句,任何地方都没有 order by 语句 我想将它们合并或不合并(全部) 即 SELECT A UNI
基本上,我有一个 struct foo { /* variable denoting active member of union */ enum whichmembe
我有一个大规模查询,用于对许多表(每个表有数千行)执行 UNION ALL,然后在返回之前输出到临时表。 旧形式: SELECT * FROM (SELECT `a` AS `Human rea
UNION 和 UNION ALL 有什么区别? 最佳答案 UNION 删除重复记录(结果中的所有列都相同),UNION ALL 则不会。 使用 UNION 而不是 UNION ALL 时会影响性能,
如果我有两个 union 行结构: struct A { A() {} ~A() {} union { vector vi; vector db
考虑下面的代码,我已经写了: #include #include union myAccess { uint16_t access16; struct { uint
我想弄清楚你从 C99 中对齐变量的地役权中得到了什么: Exception to strict aliasing rule in C from 6.5.2.3 Structure and union
我正在通过 UNION 或 UNION ALL 从多个表中选择一列外键。 当重复无关紧要时,通常建议使用 UNION ALL 而不是 UNION 来解决性能问题。但是,在我的调用 PHP 脚本中,循环
在 C++ 中,union 可以包含静态成员,在类的情况下,这些成员属于一个类,因此对所有对象都是通用的。 union U { long l; int i; static long
任何人都可以提及普通和匿名 union (或结构)之间的区别吗?我刚找到一个: 不能在匿名 union 中定义函数。 最佳答案 您不需要点运算符“.”访问匿名 union 元素。 #include
我可能把这个复杂化了.. 我正在尝试在 Arduino 上用 C 语言为嵌入式应用程序制作一个相当可重用的分层菜单系统。我有结构来表示不同类型的菜单项,包括那些子菜单,以及这些菜单项的 union 是
我是一名优秀的程序员,十分优秀!