我最近 相结合的三元运营位域访问时遇到一个棘手/有趣的问题,该代码已被简化足以暴露只是问题。位域三元操作作为左值
#include "stdafx.h"
#include <stdint.h>
typedef union
{
struct
{
uint32_t Bit_0_1 : 2;
uint32_t Bit_2 : 1;
uint32_t Bit_3_To_31 : 29;
} BitField;
uint32_t RawValue;
} UnnamedUnion;
int _tmain(int argc, _TCHAR* argv[])
{
UnnamedUnion a;
UnnamedUnion b;
a.RawValue = 0;
b.RawValue = 0;
//Version 1. Works
if (1 == 1)
{
a.BitField.Bit_0_1 = 0;
}
else
{
b.BitField.Bit_0_1 = 0;
}
printf("Reg value : %u\n", a.RawValue);
//Version 2. Also works
(1 == 1 ? a.RawValue : b.RawValue) = 1;
printf("Reg value : %u\n", a.RawValue);
//Version 3. Crashes!
(1 == 1 ? a.BitField.Bit_0_1 : b.BitField.Bit_0_1) = 2;
printf("Reg value : %u\n", a.RawValue);
getchar();
return 0;
}
请注意,版本1,2,3都是等效的表达式。我对这个 是如何发生的我有我的假设,因为我从来没有编写过编译器,但是想听听大家的想法!
更新:确认失败既VS 2012 更新:代码被再次编辑,真正把精力放在问题孤单。 (没有了铸造)
我想你正在使用VC,究竟是什么版本?我用你的代码尝试了gcc和clang,没有崩溃,打印0,1,2。 – 2014-09-02 22:31:36
看起来像(特别是你的第二次更新消除了可能的别名红鲱鱼),你已经发现了MSVC中的一个codegen错误。您应该在connect.microsoft.com上打开一个错误报告。 – 2014-09-03 01:34:00
感谢您的精彩见解。票证已提交:https://connect.microsoft.com/VisualStudio/feedbackdetail/view/962553/codegen-bug-in-accessing-bitfield-in-ternary-operations-as-lvalue – user3788697 2014-09-03 05:10:25