Confusion about auto keyword in C++ [duplicate]
Asked Answered
H

4

24

I'm confused by the following piece of code:

#include <iostream>
using namespace std;

int *foo()
{
   //Operation
}

int main ()
{
        auto int ret = foo();
}

I compiled the above code under GCC, but I got the following error:

error: two or more data types in declaration of 'ret'
         auto int ret = foo();

But, if I remove int type, like so:

auto ret = foo();

then it runs successfully.

auto is a storage class and int is a data type, then why do I get the error "two or more data types" in the first case?

Heikeheil answered 12/4, 2017 at 6:22 Comment(6)
Are you a time traveler from the past?Joleen
I'm not being rude but I've never seen anyone use auto as a storage-class specifier in the wild. I think that's why people accepted it could be re-purposed. Anyway now (C++11 on) it means automatically deduce type and it's awesome.Lobbyism
Yep, they agreed to change it because they never found evidence of a single usage outside of compiler conformance test suites.Keeton
auto keyword strange behavior in C++11Highsmith
people who are voting this as off-topic are wrong. this is a legit question, but a duplicateHarkey
I blame old textbooks that are still being circulated.Bicapsular
O
43

auto is not a storage class. It used to be, before C++11. But it was completely useless, so the keyword was re-purposed to allow automatic type inference. So when you say:

auto int ret = foo();

You are basically declaring the object to have 2 types (or possibly the same type twice), and that is an error. And when you say:

auto ret = foo();

The type of ret is determined by whatever the function foo returns, which is int* in this case.

Oatmeal answered 12/4, 2017 at 6:25 Comment(1)
Note that auto is still a storage class in C, even in the latest revision of the standard. It's just as useless there as it is in C++, but the C committee tends to be much more conservative about messing with the reserved words.Crocein
E
33

auto is a storage class

That used to be true before C++11 but not any more.

Starting from C++11, the meaning of the word has been changed. It is now used to automatically deduce types. See http://www.stroustrup.com/C++11FAQ.html#auto.

Why in first case I got an error "two or more data types"?

By using

auto int ret = foo();

you are trying to specify two types for ret -- one deduced and the other explicitly specified.

If you want to use an explicitly specified type, you can use:

int ret = *foo(); // Since foo() returns a pointer.

or

int* ret = foo();

or you can let the compiler deduce the type by using:

auto ret = foo();  
Exanimate answered 12/4, 2017 at 6:26 Comment(0)
A
10

auto is NOT a storage class (not anymore since C++11) C++11 brings the keyword allowing the compiler to infer what is the type required for the variable you are declaring.

so basically doing auto int myVar is as invalid as string double myVar2 or bool long myVar3... the variable can have only one data type defining it, and in your case the keyword auto does that...

how to get rid off the error:

Remove the int type and just use auto, doing so will let the compiler to *AUTO***matically infer that type of the variable **ret is exactly that from what foo() returns :) just genial!

auto ret = foo();

from the doc:

For variables, specifies that the type of the variable that is being declared will be automatically deduced from its initializer. For functions, specifies that the return type is a trailing return type or will be deduced from its return statements (since C++14). for non-type template parameters, specifies that the type will be deduced from the argument

Apologist answered 12/4, 2017 at 6:23 Comment(0)
P
4

You wrote that:

auto is a storage class

but this is no more true in C++11 (or later). The auto keyword has been reused for something completely different (some limited kind of type inference). The former C++03 or C99 auto storage class is now (in C++11) always implicit and should not use the auto keyword.

(if you like type inference, C++11 is not doing it very well, but C++14 or C++17 have progressed on it; Ocaml has a much more powerful and interesting Hindley-Milner type inference which is more "global"; that is why I wrote "some limited kind")

Pantheism answered 12/4, 2017 at 6:26 Comment(8)
Why provide an answer when you are not sure what auto does in modern C++?Subtreasury
What make you think I am not sure? Actually, I am pretty sure of what I have written. And auto is doing some very limited type inference (much less powerful than what Ocaml has, for a counter example). Hence the some adjectivePantheism
Not the downvoter, but I'm curious -- what, in a nutshell, is missing from auto that OCaml does?Sheik
Ocaml's (actually HM) type inference is computing the domain and target of functions globally, not just on one single expression.Pantheism
@BasileStarynkevitch I think c++14 (but not c++11) has type inference for functions (and lambda expressions) as well, see en.cppreference.com/w/cpp/language/autoWaterfront
This reads like a "C++ is dumb, am I rite?" rant. The comparison to Ocaml provides no value in understanding what the C++ auto does or in answering the question.Seel
@Seel The Ocaml comparison was edited in for clarification after someone complained about the expression "some limited type of type inference" and confused it for ignorance.Estellaestelle
You said the automatic storage duration is now (in C++11) always implicit. But it always was implicit, all the way back to C++98 and C89, so that hasn't changed.Mathildamathilde

© 2022 - 2024 — McMap. All rights reserved.