整数类型应该显式转换(例如"int"到"无符号")还是只会增加混乱?

Should integer types be cast explicitly (eg `int` to `unsigned`) or does this just add clutter?

本文关键字:quot 混乱 增加 无符号 int 类型 显式转换 整数 例如      更新时间:2023-10-16

这是一个非常小的问题,所以如果它太宽泛或可能是重复的,我深表歉意。我搜索并发现了几个关于隐式整数转换如何工作的问题,但没有一个询问它是否是一件好事。我通常根本不会关心这一点,但是编译器给出的关于隐式转换的所有响亮而恼人的警告让我怀疑这是否被认为是一个问题。

作为一个简单的示例,下面是一个代码片段,它调用一个函数,该函数采用链表、整数(索引(和无符号整数(范围(,该函数从链表中删除指定的范围。

const int64_t first = foo;
const int64_t last  = bar;
const int     diff  = last - first; /* int for example's sake */
/* ... */
ll_delete_range_at(baz->ll, first+1, diff-1);

死得很简单;不是很有趣。但是 clang 抱怨传递给函数的值被缩短了,在第二种情况下,符号被改变了。假设我知道(就像我在这里所做的那样(不会有溢出问题,并且值总是正数,这实际上是一个问题吗?应该明确地这样投射吗?

ll_delete_range_at(baz->ll, (int)(first+1), (unsigned)(diff-1));

据我了解,这只会增加混乱并明确声明程序员知道正在完成的强制转换并确信它们没问题。这值得混乱吗?

频繁转换导致的混乱是体系结构不良的标志,而不是显式强制转换错误的标志。

  1. 如果您知道特定变量或成员将始终处于特定范围或大小中,请从一开始就使用适当的类型声明它们。

  2. 如果你必须使用的类型需要用特定的范围或大小声明,那么这是有原因的,并且这个原因在你使用它们的任何地方都是有效的,所以在整个代码中坚持使用类型。

  3. 如果您有必须强制转换的特殊情况(例如,当组合使用不同类型的两个库时(,则将该强制转换封装在具有适当错误处理的帮助程序函数或包装类中。

int>应该对 sndunsigned进行 C 样式的转换,因为根据我的经验,不小心给他们提供了指针,它变成了重新解释的转换。 使用static_cast

其次,这些转换是等待发生的错误的标志;如果int不符合int64_t,我们只是得到了一个未指定的溢出。 而2^31上方的大量无符号值可能不是我们在diff==0时要删除的元素数量。

因此,从这个意义上说,它们是代码存在危险问题的出色文档。

当前的程序员"知道"这些值是安全的。 从现在起7年,几个月或几天后的不同程序员"知道"任何有效的64位值都可以用于firstlast,并且0diff是合理的,以后的代码不应该窒息。

描述 diff 不能为 0 且两个 64 位值必须在 2^31-1 以内的代码协定,使这里的代码气味更加明显。

所有这些都来自一对无害的可怕 C 样式转换和一些数字上可疑的函数调用。

显式转换比隐式转换更好,但类型转换本身在这里充满了问题。 通常,类型更改是错误和栅栏错误即将到来的迹象。 防御性编程并处理边界检查,除非您知道代码处于关键性能路径中;然后,在关键性能路径中获取正确的类型。