在返回中C++类型转换优先级



我有一个代码正在更改为以 64 位模式编译,以前由于各种原因它在 Win32 中编译。 这导致一些清理工作来解决一些警告,所以我正在挑选代码并找到如下所示的内容:

class foo 
{
public:
    int foo() { return data_.size()-1; }
private:
    std::vector<int> data_;
};

STL 容器上的 size(( 方法返回无符号值。 返回值被强制转换为有符号整数值,因此会在某个时候发生转换。

不过,我不确定这里的优先级。 size(( 返回的值是否会转换为 int,然后减去 1,如果大小为零,这将导致返回值为 -1? 或者我们会从一个无符号的 int 中减去 1,如果调用它时容器为空,可能会做坏事?

谢谢!

它将是无符号的 = 无符号的 - 1; 返回有符号(无符号( 其中无符号(0( - 1 == 无符号(最大值(

从 4.7 积分转换

整数类型的 prvalue 可以转换为另一个 prvalue 整数类型。无作用域枚举类型的 prvalue 可以是 转换为整数类型的 PR值。如果目标类型为 无符号,结果值为最小无符号整数全等 到源整数(模 2n,其中 n 是用于 表示无符号类型(。[注:在二的补语中 表示,这种转换是概念性的,没有变化 在位模式中(如果没有截断(。— 尾注 ] 如果 目标类型是有符号的,如果可以,则值保持不变 以目标类型(和位域宽度(表示;否则 该值是实现定义的。

因此,任何大于最大有符号值的无符号值都会导致实现定义的行为。

如果大小为 0,则结果不是 -1,而是一个非常大的整数"18446744073709551615"(无符号(max((。

#include <vector>
#include <iostream>
int main()
{ 
    std::vector<int> nums {};
    std::cout << "nums contains " << nums.size()-1 << " elements.n";
    // nums contains 18446744073709551615 elements.
}

http://coliru.stacked-crooked.com/a/a69d4af99ba77f47

data_.size()-1被计算为无符号整数时。当data_.size() 0时,该函数可以返回一个非常大的正数而不是-1

您的最佳选择:

int foo() { int s = data_.size(); return s-1; }

下一个程序返回i=-1std::numeric_limits<unsigned>::max()的位模式是int -1之一。这就是您的代码在 w32 中工作的原因。

#include <iostream>
#include <limits>
int main() {
  std::cout << "i=" << static_cast<int>(std::numeric_limits<unsigned>::max()) << 'n';
}
/*
  Local Variables:
  compile-command: "g++ test.cc -o a.exe && ./a.exe"
  End:
*/

但是,您的代码依赖于有符号整型和无符号整型的转换。类型必须适合!因此,更好地使用std::ptrdiff_tstd::size_t

#include <iostream>
#include <limits>
int main() {
  std::cout << "i=" << static_cast<std::ptrdiff_t>(std::numeric_limits<std::size_t>::max()) << 'n';
}
/*
  Local Variables:
  compile-command: "g++ test.cc -o a.exe && ./a.exe"
  End:
*/

你的第二个猜测是正确的。通常,计算表单的任何表达式

exp1 op exp2

在步骤中工作

  1. 评估exp1
  2. 评估exp2
  3. exp1exp2的值应用op

注意:步骤 1 和 2 可以按任何顺序出现。关键是在应用运算符之前计算每个操作数

因此,在这种情况下,exp1将首先评估为unsigned int值,并且可能会产生不良影响。