2

Consider the 2 snippets:

using x = int*;

int main () {
  const x a = new int(3);
  *a = 5;
}

and

int main () {
  const int* a = new int(3);
  *a = 5;
}

The first compiles, while the second doesn't

--> using is not equivalent to simply "plugging in" the type and then parse the line.

Are there more differences between using using and "inlining" the type directly?

nnolte
  • 1,628
  • 11
  • 25
  • 6
    What is `const` in each? Can you tell? – Fred Larson Jun 22 '18 at 15:25
  • 1
    The former declares a constant pointer to non-const data; the latter declares a non-const pointer to constant data. Naturally the latter won't work with `*a = ...`. It's all about where `const` attaches itself. There are probably a hundred dupes of this question. Time permitting, I'll try and hunt some down. Fyi, this isn't unique to `using`. Set it up with `typedef` as well. – WhozCraig Jun 22 '18 at 15:26
  • first: the pointer is const; second: the int – nnolte Jun 22 '18 at 15:26
  • Exactly! So what surprises you? – Fred Larson Jun 22 '18 at 15:27
  • 2
    @FredLarson at all, OP did not express surprise with the outcome. Instead, the question is **Are there more differences between using using and "inlining" the type directly?** Any dup closure with the question which would ask 'why the behavior is different' would be incorrect. – SergeyA Jun 22 '18 at 15:30
  • i was aware of that, and i think it makes sense that it is like that. But in my (admittedly short) path of learning c++, i never saw a difference between plugging the type in directly and typedef'ing it. and i just wondered if this is the only case where it makes a difference – nnolte Jun 22 '18 at 15:30
  • @WhozCraig this is not the question OP asks. – SergeyA Jun 22 '18 at 15:31
  • 1
    @kawillzocken I'm confused then. You seem to be asking if two different things have any "more differences" (and that probably isn't accurate either). Wasn't one enough? The subtlety of hiding a pointer-to-type in an effective type alias will often rear things like this, which is one reason it is typically *discouraged*. Is your question whether there are any *other* reasons besides the one you've shown? – WhozCraig Jun 22 '18 at 15:37
  • @WhozCraig i was simply wondering about additional differences and examples where those are relevant – nnolte Jun 22 '18 at 16:03
  • Using `volatile` will have the same difference, I think. I am not certain since it's something I rarely, if ever, use. – R Sahu Jun 22 '18 at 16:05

2 Answers2

6

The difference in interpretation is due to the way C++ declarations deal with pointer const-ness, which borrows its semantics from C. Basically, const int* x and int * const x mean different things, as explained in this Q&A.

In turn, this interpretation is due to the way the "anonymous" pointer types are derived syntactically: language designers decided to assigning const-ness to the pointed-to value, not the pointer itself, when const is at the front of the declaration.

Note that the same thing happens when you typedef a pointer type:

typedef int* x;

int main () {
    const x a = new int(3);
    *a = 5; // Works fine
    return 0;
}

Essentially, adding a using or typedef makes C++ treat int* as a single type, with only one way of assigning const-ness. On the other hand, writing int* directly is treated as a "derived" pointer type, which is governed by a different set of rules.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • 3
    This is not the answer to the question as asked. – SergeyA Jun 22 '18 at 15:56
  • @SergeyA My hope here is that once OP understands where this difference is coming from, he'd have no problem figuring out the "are there more differences" question on a case-by-case basis. In a way, this is a fish-vs-fishing-rod situation: once you explain the root cause, all the specifics become obvious. – Sergey Kalinichenko Jun 22 '18 at 16:03
1

This is related to the east-const (const on the right) / west-const (const is on the left) issue.

conston the left is only allowed only in one place: in the beginning of a type declaration. The rule is const is on the right to the type which it applies. And when it is written on the left, it is the same as been on the right of it's type.

So:

const int i1;

int const i2;

Is the same. (constant int)

And:

const int* i3;

int const* i4;

Is the same. (a pointer to constant int)

But with using we have a different situation.

 const X i5;

 X const i6;

Are the same.

So when we substitute for X the type we get:

 int * const i6;

Which is a constant pointer to a (non-constant) int.

This is what you have to look out for.

Robert Andrzejuk
  • 5,076
  • 2
  • 22
  • 31