关键字"auto"接近临界点

Keyword "auto" near critical points

本文关键字:临界点 接近 auto 关键字      更新时间:2023-10-16

可能重复:
多少是太多与C++0x自动关键字

我发现在临界点附近使用"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(上的输出。它们不同:在Ideone(gcc-4.5.1(上的循环中,"i"仍然是2147483647,在LWS(gcc-4.7.2(中溢出。但它们都不是预期的结果:10个循环,每次+1。

我应该避免在临界点附近使用"自动"吗?或者我如何在这里恰当地使用"auto"?

更新:有人说"你可以在任何地方使用auto。"在这个帖子中你告诉我。我认为这不太正确。类型"long-long-int"比这里的类型"int"更合适。我想知道哪里可以安全使用"auto",哪里不能。

更新2:Herb Sutter文章的解决方案4(b(应该已经回答了这个问题。

如果变量的类型是正确的,那么您应该只依靠类型推导来计算变量的类型。在这里,编译器推断它是一个int,就标准而言,这是正确的,但您的特定问题需要另一个范围更大的类型。当您使用auto时,您说的是"编译器最了解",但编译器并不总是了解所有内容。

您不会在这里使用auto,就像您不会使用int一样。你可以让你的文字有更高的秩(把LLL放在它后面——尽管它们不能保证比你的int大(,然后auto会推导出一个更大的积分类型。

更不用说auto在这种情况下真的不会为您节省任何费用。auto通常用于避免键入长的、难看的类型或您不知道的类型。在这种情况下,类型并不长,也不难看,您确实知道。

auto只是一个语法糖。它不是一个类型,它只是推断右侧应该是什么类型,并以此决定变量的类型。

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

除非显式更改其类型,否则数字文字(不带小数点(始终为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.

您对auto的期望过高。您的期望是auto将自动推导出类型,这最适合您将对变量执行的操作。这是语义分析,编译器不应该这样做(通常情况下,他们不能这样做(。他们不能期待你以后在程序中使用你声明的变量的方式。

auto关键字只会使您省去在左侧显式写入右侧出现的表达式类型的负担,从而避免可能的冗余和与之相关的所有问题(如果右侧的表达式类型发生变化,该怎么办?(

也就是说,所有其他答案都是正确的:如果你想让变量i不溢出,你应该给它分配一个long long文字(使用LL后缀(。