将布尔值或浮点数分配给int32_t是否安全?

Is it safe to assign bool or float to int32_t?

本文关键字:是否 安全 int32 布尔值 浮点数 分配      更新时间:2023-10-16

我有一个c++项目,该项目具有int32_t成员数据类型的结构,我想为其分配boolfloat变量,这会破坏变量的值吗?如果是,除了更改结构成员数据类型之外,我还应该做什么?

每当编译器必须在需要另一种类型的上下文中使用某个类型的值时,都会执行隐式转换。

隐式转换的规则很多,但在浮点积分转换下,有以下段落:

浮点类型的 prvalue 可以转换为任何 整数类型。小数部分被截断,即 小数部分被丢弃。如果该值无法放入 目标类型,则行为未定义(即使目标 类型是无符号的,模算术不适用)。如果 目标类型为 bool,这是一个布尔转换(见下文)。

因此,您可以安全地分配浮点类型(例如floatdouble) 为整数。如果该值可以容纳,则小数部分将被截断。这意味着数据丢失,并且可能是错误的根源,或者可能是某些应用程序中故意这样做的。请注意,浮点类型的范围大于int32_t,如果无法存储该值,则根据标准,它是未定义的行为。

另一方面,布尔值在任何情况下都可以安全地分配给整数类型:

如果源类型为 bool,则值 false 将转换为零,并且 值 true 将转换为目标类型的值之一 (请注意,如果目标类型为 int,则这是一个整数 促销,而不是整数转换)。

您分配的值将转换为int32_tbool值不会丢失任何东西。float值将被截断。只会存储它的组成部分。

如果是,除了更改结构成员数据类型之外,我还应该做什么?

这取决于要存储的值的类型是在运行时还是在编译时确定的。如果在运行时确定,则可以使用 std::any 代替int32_t

#include <any>
struct MyStruct {
std::any val;
};
// ...
MyStruct s;
s.val = true; // val now contains a bool
s.val = 3.1415; // val now contains a double
s.val = 3.1415f; // val now contains a float
s.val = 42; // val now contains an int

如果类型是在编译时确定的,则可以创建一个结构模板:

template <typename T>
struct MyStruct {
T val;
};
// ...
MyStruct<bool> s1;
s1 = false;
MyStruct<float> s2;
s2 = 3.1415;