c++ - 将 C++ 引用从 unsigned char 转换为 double& 安全吗?

标签 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 },
};

尝试通过表分配栏时,一切正常。

entries[0].ref = 1.0;

如预期的那样,这会导致 entries[0].ref == 1.0bar == 1.0。但是,当通过表分配 foo 时...

entries[1].ref = 1.0;

这会以某种方式导致值不匹配,就好像无法正确解释引用,或者甚至没有引用正确的对象。在这个赋值之后,entries[1].ref == 1,但是 foo == 0

这是语言未定义的行为,还是我在滥用或滥用某些东西?这可能是标准版本的差异,因为我用 C++17 在 repl.it 上测试了一个类似的例子,它按我的预期工作。在 MATLAB 中使用 mex 并使用 Visual Studio 2017 作为编译器使用我们的目标编译器进行编译时,这按预期工作。

最佳答案

读一个人char作为double是未定义的行为,因为它打破了类型别名规则,这就是您正在做的事情。从 char 转换double 的值使用 static_cast<double> 的值是完全正常和定义的。

一般可以重新解释double作为char ,但仅限于特定场景:

Type aliasing

Whenever an attempt is made to read or modify the stored value of an object of type DynamicType through a glvalue of type AliasedType, the behavior is undefined unless one of the following is true:

  • [...]
  • AliasedType is std::byte (since C++17), char, or unsigned char: this permits examination of the object representation of any object as an array of bytes.

(参见 reinterpret_cast conversion)

所以我们可以检查 double (动态类型)作为 char[] (AliasedType),但反之则不然。考虑一个事实 char恰好是一个字节大并且 double很可能是 8 个字节大。重新解释引用时剩余的 7 个字节的值是多少?它是未定义的。

请注意,在转换引用时,像 (double&) 这样的 C 风格转换相当于reinterpret_cast<double&> .我建议使用像 const_cast 这样的显式 C++ 转换, reinterpret_caststatic_cast以免混淆。

关于c++ - 将 C++ 引用从 unsigned char 转换为 double& 安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63709841/

相关文章:

C++ 继承问题

c++ - 实现隐式转换为 char* 的 String 类 (C++)

Java "extending"一个对象

mysql - Ruby mysql gem - 如何在查询时避免日期时间自动转换为字符串

c++ - 为什么这段看似简单的 C++ 代码会产生段错误?

c++ - 为什么将 const std::string& 传递给构造函数不允许将其绑定(bind)到初始化列表中的 const std::string& 成员变量?

c++ - 如何避免两步初始化

c++ - libstdc++ 没有实现 std::stoi 吗?

java - ArrayList<int> 与 ArrayList<int[]>?

c++ - 如果 T 可转换为 U,则将 class<T> 转换为 class<U>