关键词“auto”临近关键点

时间:2012-12-29 12:54:29

标签: c++ loops c++11 auto

  

可能重复:
  How much is too much with C++0x auto keyword

我发现在关键点附近使用“auto”可能会导致一些问题。

这是示例代码:

#include <iostream>
#include <typeinfo>
#include <limits>

using std::cout;
using std::endl;
using std::numeric_limits;
using std::cerr;

int main() {
   auto i = 2147483647 /* numeric_limits<int>::max() */ ;
   cout << "The type of i is " << typeid(i).name() << endl;

   int count = 0;
   for (auto i = 2147483647; 
        i < 2147483657 /* numeric_limits<int>::max() + 10 */ ; ++i) {
       cout << "i = " << i << " " << endl;

       if (count > 30) {
           cerr << "Too many loops." << endl;
           break;
       }
       ++count;
   }

   return 0;
}

“auto”决定“i”的类型是整数,但整数的上限是2147483647,这很容易溢出。

这是Ideone(gcc-4.5.1)LWS(gcc-4.7.2)上的输出。它们是不同的:“i”在Ideone(gcc-4.5.1)的循环中仍然是2147483647,在LWS(gcc-4.7.2)上溢出。但是没有一个是预期的结果:10个周期,每次+1。

我应该避免在关键点附近使用“自动”吗?或者我如何恰当地使用“自动”?

更新:有人说“在任何地方都可以自动使用”。在这个thread你告诉我。我不认为这是对的。类型“long long int”更适合这里的“int”类型。我想知道哪里可以安全地使用“自动”,哪里不能。

更新2:Herb Sutter的the article解决方案4(b)应该回答了这个问题。

4 个答案:

答案 0 :(得分:0)

如果变量的类型正确,您应该只依靠类型推导来计算出变量的类型。在这里,编译器将其推断为int,就标准而言正确,但是您的具体问题需要另一种具有更大范围的类型。当你使用auto时,你会说“编译器最了解”,但编译器并不总是知道所有内容。

您不会在此使用auto,就像您不使用int一样。你可以让你的文字具有更高的等级(坚持LLL之后 - 尽管它们不能保证比你的int更大,然后auto会推导出更大的整数类型。

更不用说auto在这种情况下确实无法保存任何内容。 auto通常用于避免键入您不知道的冗长,丑陋的类型或类型。在这种情况下,类型不长又丑,你知道它。

答案 1 :(得分:0)

auto只是syntactic sugar。它不是一种类型,它只是推断出右侧应该是什么类型,并由此决定变量的类型。

如果给它文字,它只会推断出编译器给出的默认类型 您只需知道实际类型是什么。

答案 2 :(得分:0)

除非您明确更改其类型,否则数字文字(不带小数点)始终为int

int x = 2147483657; // 2147483657 is treated as an int.
                    // If it does not fit tough it will be truncated
                    // according to standard rules.

long x = 2147483657L; // The L suffix tells the compiler to treat it as a long.
                      // Here you will get the correct value assuming long is larger than int.

在你的情况下:

for(auto i = 2147483647;i < 2147483657;) // is not going to work as i is always 
                                         // an int and literal overflows.

// Try correct types:

for(auto i = 2147483647L; i < 2147483657L;++i) //Now it should work correctly.

答案 3 :(得分:0)

你期待auto过多。您的期望是auto会自动推断出类型,这种类型最适合您对变量 将要执行的操作。这是语义分析,编译器不希望这样做(大多数情况下,他们不能)。他们无法期待您将在程序中使用稍后声明的变量。

auto关键字只会让您免于在左侧显式写入右侧出现的表达式类型的负担,避免可能的冗余以及与之相关的所有问题(如果表达式的类型如何,正确的变化?)

这就是说,所有其他答案都是正确的:如果您希望变量i不溢出,则应为其分配long long字面值(使用LL后缀)。< / p>