返回时C ++类型转换优先级

时间:2014-05-16 16:03:57

标签: c++ types stl casting type-conversion

我有一个代码被更改为在64位模式下编译,之前由于各种原因在Win32中编译。这导致了一些清理工作,以解决一些警告,所以我通过代码挑选并找到了类似这样的东西:

class foo 
{

public:
    int foo() { return data_.size()-1; }

private:
    std::vector<int> data_;
};

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

我不确定这里的优先顺序。 size()返回的值是否会被转换为int然后减去1,如果size为零,这将导致返回值为-1?或者我们会从unsigned int中减去1,如果在调用它时容器是空的,可能会做坏事吗?

谢谢!

5 个答案:

答案 0 :(得分:3)

它将是unsigned = unsigned - 1; return signed(unsigned)where unsigned(0) - 1 == unsigned(max)

来自4.7积分转换

  

整数类型的prvalue可以转换为另一个的prvalue   整数类型。可以使用无范围枚举类型的prvalue   转换为整数类型的prvalue。如果目的地类型是   无符号,结果值是最小的无符号整数全等   到源整数(模2n,其中n是用于的位数   代表无符号类型)。 [注意:用二进制补码   表示,这种转换是概念性的,没有变化   在位模式中(如果没有截断)。 - 结束说明] 如果   目标类型已签名,如果可以,则值不变   以目标类型(和位字段宽度)表示;除此以外,   该值是实现定义的。

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

答案 1 :(得分:1)

如果大小为0,则结果不是-1,而是一个非常大的整数&#34; 18446744073709551615&#34; (无符号(最大))。

#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

答案 2 :(得分:0)

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

exp1 op exp2

适用于

步骤
  1. 评估exp1
  2. 评估exp2
  3. opexp1
  4. 的值应用exp2

    注意:步骤1和2可以按任何顺序发生。点是在应用运算符之前评估每个操作数

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

答案 3 :(得分:0)

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

您最好的选择:

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

答案 4 :(得分:0)

下一个程序返回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:
*/