tags:

views:

389

answers:

4

mmm, I have just a little confusion about multiple auto declarations in the upcoming C++0x standard.

auto a = 10, b = 3.f , * c = new Class();

somewhere I read it is not allowed. The reason was(?) because it was not clear if the consecutive declarations should have the same type of the first one , (int in the example) , or not.

Possible translation 1:

int a = 10; 
int b = 3.f; 
int * c = new Class ();

causing an error

Possible translation 2:

int a = 10;
float b = 3.f;
Class * c = new Class ();

how it is resulted in the standard?

If I can say my POV, translation #2 was the most obiouvs, at least for me that I'm a regular C++ user . I mean, for me "every variable declared is of the same declared type", witch is auto. Translation #1 would be really un-intuitive to me.

Good Bye QbProg

A: 

The first one would kind of line up with how type inference works in the return type of the ?: operator.

Eclipse
+4  A: 

The draft standard section 7.1.6.4 implies that you can't mix types like in possible translation 2. So neither possible translation is valid.

Kristo
Possible translation 1 would never be valid, because deducing T* for Class* can never get T=int according to template argument deduction rules, which are used in this case
jpalecek
Thanks, I've edited my answer accordingly.
Kristo
+5  A: 

It's probably not the latest, but my C++0x draft standard from June 2008 says you can do the following:

auto x = 5; // OK: x has type int
const auto *v = &x, u = 6; // OK: v has type const int*, u has type const int

So unless something has changed from June this is (or will be) permitted in a limited form with a pretty intuitive interpretation.

The limitation is that if you do want to string multiple auto declarations like this (using the example above), it works because the inferred type of v and u have the same 'base type' (int in this case) to use an inexact term.

If you want the precise rule, The draft standard says this:

If the list of declarators contains more than one declarator, the type of each declared variable is determined as described above. If the type deduced for the template parameter U is not the same in each deduction, the program is ill-formed.

where the "deduced template parameter U" is determined by:

the deduced type of the parameter u in the call f(expr) of the following invented function template:

 `template <class U> void f(const U& u);`

Why they've come up with this rule instead of saying something like:

auto a = 10, b = 3.f , * c = new Class();

is equivalent to:

auto a = 10;
auto b = 3.f;
auto * c = new Class();

I don't know. But I don't write compilers. Probably something to do with once you've figured out the the auto keyword replaces, you can't change it in the same statement.

Take for example:

int x = 5;
CFoo * c = new CFoo();

auto  a1 = x,       b1 = c; // why should this be permitted if
int   a2 = x, CFoo* b2 = c; // this is not?

In any case, I'm not a fan of putting multiple declarations on the same statement anyway.

Michael Burr
+1  A: 

There are few points which I think help contribute to the current wording. The first is consistency. If you write a declaration such as:

int j;
int i = 0, *k = &j;

Then, the two types both use int somewhere in their type. It is an error for example, if 'j' was a 'const int'. Having auto work the same is "consistent" with the current model for such declarations.

There is then a practical advantage from a compiler writer's perspective. There already exists the machinery in compilers to perform type deduction for a function call (which is how auto is described as operating). The above rule is consistent with the rule that deduction for a template parameter must result in the same type:

template <typename T> void foo (T, T*);

void bar ()
{
  int i;
  const int j = 0;

  foo (i, &i);  // OK deduction succeeds T == int
  foo (i, &j);  // ERROR deduction fails T == int or const int.
}

An easy implementation for auto is to reuse the existing mechanics to deduce the type for auto, and because of the consistency with current behaviors the result will not be too surprising to people.

Finally, and this is probably the most important point in my opinion. The current model is conservative and works very similarly to existing language constructs in C++. Therefore the chances of it resulting in a show stopping language bug are very slim. However, the current model can easily be expanded in the future to contain the other examples you list in your question.

What's more, that expansion will not break code that uses the current wording of auto. Consider if they did this the other way round. If the expanded version of auto was the first version, and this resulted in some weird and fatal flaw with the keyword then it would require the removal of a language feature from the standard - something which almost never happens as it most likely breaks code.

Richard Corden