4

(Quite basic question: ) I found both of below ways generates int * type. May I know which one is more proper?

int i = 42;
auto a = &i;
auto *b = &i;

(I tried to relate the pointer example to reference example: auto c = i; and auto &d = i;. But it seems the analogy does not work here.)

Edit: I also found another (closely related) example strange:

auto i = 42, p = &i; // fails at compilation
auto i = 42, *p = &i; // passes at compilation

Why? In both cases the initializers have the same base type int (which should make both case pass), isn't it?

user3791991
  • 129
  • 6

2 Answers2

1

IMO none of them is really "proper", since all of them are hard to read/understand without being able to lookup the actual type of i. So just use int *c = &i;. If you're unsure about the type changing later on, use a typedef with a custom type rather than int.

Personally, I'm trying to avoid auto wherever I can, unless it's really something isolated or easy to understand like an iterator in a for() loop.

Edit: If you really have to use auto for whatever reason (let's assume some more complex scenario), then I'd definitely use auto a = ... rather than auto *a = .... Without specifically defining a pointer you're able to replace the actual datatype with something providing a similar interface, e.g. switching from a raw pointer to a smart pointer - you're not restricted to pass/store a raw pointer.

Edit 2: Considering your addition:

auto i = 42, p = &i; // fails at compilation

This won't compile? Pretty obvious. If you declare multiple variables in one line, all of them will get the same datatype. Utilizing auto here won't mean that the actual meaning of auto is reevaluated for each entry. Instead, it's "one fits all", and if that fails (which is the case here), it won't compile.

If you add casts to the assignments representing the actual types being assigned, it becomes more obvious:

auto i = (int)42, p = (auto*)&i;

Now auto is resolved to int:

int i = (int)42, p = (int*)&i;

Splitting this into two lines to make it even more obvious:

int i = (int)42;
int p = (int*)&i; // Whoopsie!
Mario
  • 35,726
  • 5
  • 62
  • 78
  • The above example is an simplified scenario for discussion. I do agree for a simple case in reality it is better to directly call out the actual type `int *`. – user3791991 Jul 05 '14 at 20:41
  • @Deduplicator: I assume due to not being able to see it being a pointer? I'd agree, but guess that's really personal preference. – Mario Jul 05 '14 at 21:00
  • 1
    Actually, I tend to disagree with avoiding `auto`. Still, wherever the type and how to write is is both obvious and relatively short, I write it myself. – Deduplicator Jul 05 '14 at 21:04
  • Guys I added two more example that looks strange, in case you would like to take into account for discussion. – user3791991 Jul 05 '14 at 21:11
  • Thumb up for the quick response. But I have a small comment on the "all of them will get the same datatype" part: per C++ primer (5ed, pg69), this datatype is only restraining the "base type". Although i is an `int`, p is an `int *`, their base type is the same so it shall pass. In the book they actually used the 2nd eg as a correct example. (But I could not figure out why the 1st e.g. fails) – user3791991 Jul 05 '14 at 21:24
  • That means that `int *a, b;` defines `int *a;` and `int b;`. The `*` isn't passed to all following variables (`int` being the base type). – Mario Jul 05 '14 at 21:28
  • @Mario Exactly! So in the example `auto i = 42, p = &i;` p 's base type is `int` (`p`'s type is a compound type int \*, whose base type is `int` ), i's base type is `int`. This match with the rule mentioned (as long as the multiple variables declared has the same base type it shall pass). So `auto i = 42, p = &i; ` shall pass, isn't it? – user3791991 Jul 05 '14 at 21:35
  • No, since you're trying to assign an integer pointer to an integer value. Ignore `auto` for now, it's confusing you. Use `int` instead and look at the line. – Mario Jul 06 '14 at 08:22
0

I would definitely always go with :

auto a = &i;

Its less obscure because the type of "a" must contain an address. Its a pointer.

This is more obscure:

auto *b = &i;

That's saying that the contents of b must be an int, making b an int* (harder to visualize)

int i = 42; 
auto a = &i; // auto resolves to an int*
auto *b = &i; // auto resolves to an int (contents of b is int), b is an auto* aka int*

auto i = 42, p = &i; // auto resolves to an int, then p must also be an int (whoops mixing types).
auto i = 42, *p = &i; // auto resolves to an int, p is an auto* aka an int*
Galik
  • 47,303
  • 4
  • 80
  • 117