-4

Possible Duplicate:
How much is too much with C++0x auto keyword

I find using "auto" near critical points maybe cause some problems.

This is the example code:

#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;
}

The "auto" decides the type of "i" is integer, but the upper limit of integer is 2147483647, that's easily overflow.

That's the outputs on Ideone(gcc-4.5.1) and LWS(gcc-4.7.2). They're different: "i" remains 2147483647 in the loops on Ideone(gcc-4.5.1) and overflows on LWS(gcc-4.7.2). But none of them is the expecting result: 10 cycles, +1 every time.

Should I avoid to use "auto" near critical points? Or How I use "auto" appropriately here?

UPDATE: Someone says "Use auto everywhere you can." in this thread you tell me. I don't think that's quite right. Type "long long int" is more appropriate the type "int" here. I wonder where I can use "auto" safely, where can't.

UPDATE 2: The solution 4(b) of the article by Herb Sutter should have answered the question.

Community
  • 1
  • 1
UniversE
  • 555
  • 2
  • 7
  • 25
  • 1
    Welcome to undefined behavior? – user541686 Dec 29 '12 at 12:57
  • Why would you need `auto` for simple integer types? What do you gain? – zch Dec 29 '12 at 12:58
  • 5
    How would your problem change if you had used `int` instead of `auto`? How is this related to type deduction? – Konrad Rudolph Dec 29 '12 at 13:00
  • 4
    Numeric literals are always int (even if they overflow). You need to use the correct suffix `L` or `UL` or `LL` or 'ULL` to correctly specify the type of the literal. – Martin York Dec 29 '12 at 13:06
  • @KonradRudolph Using auto in loops is usual. That's just a simple example. The real codes should be more complex. I hope "auto" can deduce the type not obvious. – UniversE Dec 29 '12 at 13:08
  • 1
    @UniversE: It does correctly deduce the type. The standard explicitly states that numeric literals are int (unless you add the appropriate suffix). It does not try and deduce the type of a literal based on the value. – Martin York Dec 29 '12 at 13:11
  • @LokiAstari The type "long long int" won't overflow. More Info: http://en.cppreference.com/w/cpp/language/types – UniversE Dec 29 '12 at 13:13
  • 3
    @UniversE That’s irrelevant. The type is deduced correctly. I still don’t understand what the problem here is. The code is semantically incorrect but that is *your* fault, not the compiler’s, because you use the wrong type for your literals. – Konrad Rudolph Dec 29 '12 at 13:14
  • 1
    @UniversE: Its not a `long long int`. its an `int` (because its numeric literal). Lots of code depends on this fact. – Martin York Dec 29 '12 at 13:17
  • @LokiAstari I know it deduces that correctly, but it also digs a trap. The one who use "auto" need to think more conditions in complex loops. That's even more troublesome than deciding types by programmers themselves. – UniversE Dec 29 '12 at 13:22
  • @LokiAstari I mean I can decide the type "long long int" here, the choice by "auto" here is not appropriate. – UniversE Dec 29 '12 at 13:26
  • @UniversE: As I have said the standard explicitly states that numeric literal are int (thus auto works as expected). Existing code depends on this fact (numeric literals are int) so it is not going to change. Also you are wrong that `long long int` is appropriate (that is platform dependent on some platforms `long int` may be enough (so obviously it is not such an easy choice)). – Martin York Dec 29 '12 at 13:37
  • @LokiAstari I know the differences of platforms. But I don't know which type is more appropriate than "long long int" here, and it makes sense on LWS(gcc-4.7.2). Can you tell me a more appropriate type? Or I need a library for extra large data sets on this condition? :) – UniversE Dec 29 '12 at 13:47
  • @UniversE: Even if you use `long long int` instead of `auto` as the type the code still fails. As the numeric literals are still int. They will be truncated first then the will be converted to long long int during assignment. So the code still fails in exactly the same way as when you use `auto`. So auto has nothing to do with the problem here. – Martin York Dec 29 '12 at 13:52
  • @LokiAstari It makes sense, no truncating, at least on gcc-4.7.2. This is [the demo on LWS](http://liveworkspace.org/code/4mMTpg$0), or as dasblinkenlight answered. – UniversE Dec 29 '12 at 14:17

4 Answers4

0

You should only rely on type deduction to work out the type of your variables if it's going to be correct. Here, the compiler makes the deduction that it's an int, which is right as far as the standard is concerned, but your specific problem requires another type with a larger range. When you use auto, you're saying "the compiler knows best", but the compiler doesn't always know everything.

You wouldn't use auto here, just as you wouldn't use int. You could make your literal have higher rank (stick L or LL after it - although they're not guaranteed to be any larger than your int) and then auto would deduce a larger integral type.

Not to mention that auto really saves you nothing in this case. auto is usually used to avoid typing long, ugly types or types that you don't know. In this case, the type is not long and ugly, and you do know it.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
0

auto is just a syntactic sugar. It isn't a type, it just infers what type the right side is supposed to be and decides that variable's type by that.

If you give it literals, it will just infer the default type it is given by the compiler.
You just need to know what the actual type is.

Yochai Timmer
  • 48,127
  • 24
  • 147
  • 185
  • I know it's not a type. I feel the most important point now is knowing where can safely use, where can't. Without that, "auto" is rather a trap than sugar. – UniversE Dec 29 '12 at 14:26
  • 1
    in c++ you always have to know the type. it just shortens the writing. if you don't know the type, figure it out, and only then use the auto. – Yochai Timmer Dec 29 '12 at 22:30
  • Yochai Timmer, [as Bjarne Stroustrup said](http://www.stroustrup.com/C++11FAQ.html#auto), "The type of tmp should be what you get from multiplying a T by a U, **but exactly what that is can be hard for the human reader to figure out**, but of course the compiler knows once it has figured out what particular T and U it is dealing with." – UniversE Dec 30 '12 at 06:35
0

An numeric literal (without the decimal point) is always int unless you explicitly change its type.

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.

In your case:

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.
Martin York
  • 257,169
  • 86
  • 333
  • 562
  • [It does not look like one `L` is sufficient in his case - you need two `L`s](http://ideone.com/31snZt). – Sergey Kalinichenko Dec 29 '12 at 13:05
  • @dasblinkenlight: That is platform dependent. LL may not be enough if sizeof(int) == sizeof(long long). I noted above the assumption that long must be larger than int for that to hold. – Martin York Dec 29 '12 at 13:09
0

You are expecting too much out of auto. Your expectation is that auto will automatically deduce the type which is best for the manipulation that you are going to perform on your variable. This is semantic analysis and compilers are not expected to do that (most often, they cannot). They can't look forward into the way you are going to use the variable you declare later on in your program.

The auto keyword only saves you from the burden of explicitly writing on the left the type of the expression appearing on the right, avoiding possible redundancy and all problems connected with it (what if the type of the expression on the right changes?)

This said, all other answers are correct: if you want your variable i not to overflow, you should assign to it a long long literal (using the LL postfix).

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451