Ric*_*ski 2 c++ casting reference
我正在尝试通过索引查找来实现用于设置各种代码元素的引用“表”。大多数基础变量都是double,但有一些是不同的类型,例如unsigned char。
这是一个简化的示例:
static unsigned char foo = 0; // Variable to set
static unsigned double bar = 0.0; // Variable to set
...
struct tableEntry {
double& ref; // Reference to one of the above
double min;
double max;
};
struct tableEntry entries[] {
{ bar, 0.0, 1.0 },
{ (double&)foo, 0x0, 0xff },
};
Run Code Online (Sandbox Code Playgroud)
尝试通过表格分配栏时,一切正常。
entries[0].ref = 1.0;
Run Code Online (Sandbox Code Playgroud)
这导致entries[0].ref == 1.0, 和bar == 1.0,正如预期的那样。但是,当通过表分配 foo 时......
entries[1].ref = 1.0;
Run Code Online (Sandbox Code Playgroud)
这会以某种方式导致值不匹配,就好像引用无法正确解释,或者甚至没有引用正确的对象。在此分配之后,entries[1].ref == 1,但是foo == 0。
这是语言的未定义行为,还是我滥用或滥用某些东西?这可能是标准版本的差异,因为我用 C++17 在 repl.it 上测试了一个类似的例子,它按我的预期工作。使用 Visual Studio 2017 作为编译器,在 MATLAB 中使用我们的目标编译器进行编译时,这无法按预期工作mex。
将个人读char作 adouble是未定义的行为,因为它违反了类型别名规则,这就是您正在做的事情。从转换char值到一个double使用值static_cast<double>是完全正常的,虽然所定义。
通常可以重新解释double为char,但仅限于特定场景:
类型别名
每当尝试通过 AliasedType 类型的泛左值读取或修改 DynamicType 类型的对象的存储值时,除非满足以下任一条件,否则行为未定义:
- [...]
- AliasedType 是
std::byte(C++17 起)、char、 或unsigned char:这允许将任何对象的对象表示检查为字节数组。
因此,我们可以将double(DynamicType) 视为char[](AliasedType),但不能反过来。考虑这样char一个事实,它正好是 1 个字节大,而且double很可能是 8 个字节大。重新解释引用时剩余 7 个字节的值是多少?它是未定义的。
请注意,在转换引用时,C 样式转换 like(double&)等效于reinterpret_cast<double&>. 我推荐使用显式的C ++类型转换喜欢const_cast,reinterpret_cast并且static_cast以避免混淆。