[问题] union 的undefine behavior

楼主: lovejomi (JOMI)   2020-06-16 00:35:43
平常真的很少用union 所以当要用的时候还是查了一下
https://en.cppreference.com/w/cpp/language/union
S s = {0x12345678}; // initializes the first member, s.n is now the active
member
// at this point, reading from s.s or s.c is undefined behavior
诶, 这不就是常看到union的标准用法吗?
于是我再找找
http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Ru-pun
恩....真的是undefined behavior.....完全颠覆我之前对union的认知
原来看到这种union { struct{} , array;} 全部都是UB...
想问一下
1. 即使他是 书本上的UB 但是不是可以说 所有已知compiler实作上都让他效果一致
也就是常用的那套手段也没什么问题, 真的这样写 也不用太苛责?
2. 如果真的不想写出UB 的程式码, 是不是只能用reinterpret_cast
例如
union Endian{
int a;
char b;
};
改用
int a = 1; char b = *(reinterpret_cast<char*>(&a));
对于reinterpret_cast每当用 都很怕是UB,
有没有什么通则可以快速确认是否转型是UB呢?
以上 (今天才知道union 这样写是UB, 实在很震惊)
作者: loveme00835 (发箍)   2020-06-16 02:09:00
你的认知应该是从 C 语言来的, 所谓的 active member就是已经建构好的物件, 如果你要改用另外一个物件就必须要先解构当前的 active member 再去建构另一个,在 C++ 里所有物件都要经过建构才能用, 只有将指标转型无视这个规则的都是 UB对于 non-class object 也是同理, 建构子/解构子一整套流程缺一不可如果懒得自己处理就改用 std::variant 吧
楼主: lovejomi (JOMI)   2020-06-16 09:49:00
可是primitive type要怎么建构解构(syntax)?如果要这样 那之前在C work的union写法 在C++是不是无法使用, 如我举例的Endian 例子...连primitive type也UB?https://ideone.com/FjHpL0 这样写却没有建构子被呼叫合理吗@@ 这样我补上解构 不就不对称了
作者: loveme00835 (发箍)   2020-06-16 10:50:00
https://bit.ly/3d22Vlr 参考 [class.union]/6.3 还有[class.union]/7https://wandbox.org/permlink/q3ZZFikhmqHmmFSK
楼主: lovejomi (JOMI)   2020-06-16 11:18:00
u.i.~int_t(); 我有私底下这样写但实在从来没看过但这也证明了 endian那种用法在C++完全是个错误?但也像我第一个问题讲的 这种UB真的是无法接受的吗?您的例子 透过placement new才会有建构子呼叫如果一开始就要用 u.s 该怎么办呢https://wandbox.org/permlink/fmObYFTkDu6k6v3k是不是 要调整s为第一个 并且 在 {{一定要写}} ?
作者: loveme00835 (发箍)   2020-06-16 11:26:00
UB 是灰色地带, 只要你确定使用的编译器行为会如你预期, 那 UB 就只是可携性比较差而已. 很多低阶的内存操作都是 UB 要靠标准慢慢补完. 可以参考 [P0593]
楼主: lovejomi (JOMI)   2020-06-16 11:50:00
恩 那 没跑到建构子是不是也是可接受?
作者: loveme00835 (发箍)   2020-06-16 12:51:00
当然不是这样说 0rz 你没有跑完 ctor 自然连 dtor 也不会跑, 尤其是对有 side-effect 的 ctor 来说更是一定要呼叫
楼主: lovejomi (JOMI)   2020-06-16 19:18:00
我对side effect这词用在这领域没什么感觉,可否给我一些延伸资讯呢 谢谢
作者: loveme00835 (发箍)   2020-06-16 20:17:00
偶觉得你还是先把基础打好
作者: CoNsTaR ((const *))   2020-06-21 11:02:00
想要有保障就用 inheritance,不要用 union 啊要用 union 就要自己人脑生成 induction principles 和检查所有 introduction/elimination

Links booklink

Contact Us: admin [ a t ] ucptt.com