0

In C++ Primer book, there is an explanation on type aliases as:

typedef char *pstring;
const pstring cstr = 0; // cstr is a constant pointer to char

They say that the following is a wrong interpretation:

const char *cstr = 0;

However it makes sense to me, to replace the typedef alias with its original meaning.

In a normal scenario without type aliasing a constant pointer is defined as:

char *const cstr = 0;

Why is it constant pointer rather than pointer to const?

Can anyone explain in clear terms because the book doesn't seem to clarify it much.

Navjot Singh
  • 678
  • 7
  • 18
  • 2
    `const` binds to the thing to its immediate left (unless `const` is the first thing, in which case it binds to the thing to its immediate right). Since `pstring` is a pointer, `const pstring` binds to the pointer. – Eljay Mar 26 '19 at 22:00
  • `2 * 3 + 1` is 7. But how come if I do `int i = 3 + 1;` and then `2 * i` it gives 8? Shouldn't the variable be replaced with its original meaning? – user253751 Mar 26 '19 at 22:02
  • Religious issue warning, but I find `const char* cstr = 0;` much more readable. I only put asterisks on the left of things when I'm dereferencing them. – Robert Harvey Mar 26 '19 at 22:02
  • @immibis: What, if anything, does that have to do with this question? – Robert Harvey Mar 26 '19 at 22:04
  • The book suggests to use it to left of variable names. e.g. `int *ptr = 0, val = 0;` Here ptr is a pointer to int while val is an integer variable. @RobertHarvey – Navjot Singh Mar 26 '19 at 22:05
  • Like I said. Religious issue. I see the * as part of the type. – Robert Harvey Mar 26 '19 at 22:07
  • However, my question is still unanswered :( – Navjot Singh Mar 26 '19 at 22:08
  • `const` applies to *whatever the type is.* In your case, the type is a pointer to a char. That's why making the asterisk part of the type (and not part of the variable name) makes more sense, even though C doesn't care which style you use. – Robert Harvey Mar 26 '19 at 22:09
  • In any case, here is the opposing viewpoint: https://stackoverflow.com/q/398395 – Robert Harvey Mar 26 '19 at 22:13

1 Answers1

2

2 * 3 + 1 is 7. But how come if I do int i = 3 + 1; and then 2 * i it gives 8? Shouldn't the variable be replaced with its original meaning?

It's because 2 * 3 + 1 is interpreted as (2 * 3) + 1, while 2 * i is the same as 2 * (3 + 1). These mean different things and work out to different numbers. When you give 3 + 1 a name, when you use the name it doesn't break up the number back into 3 + 1 in order to only multiply the 3.

The reason that const char * is different from const pstring is very similar. const char * is interpreted as (const char) * i.e. a pointer to a constant char. But const pstring is the same as const (char *) i.e. a constant pointer to a char. pstring is a whole type by itself, and when you do const pstring it doesn't split up the char * in order to make the char part const.

Note: if you did #define pstring char * then const pstring would be the same as const char *, because macros (#defines) are just treated as text replacements.

user253751
  • 57,427
  • 7
  • 48
  • 90
  • I still don't see what your math has to do with any of this. – Robert Harvey Mar 26 '19 at 22:20
  • Shouldn't `const (char *)` be explained as constant pointer rather than pointer to a constant char?? @immibis – Navjot Singh Mar 26 '19 at 22:27
  • You don't see the analogy between `(2 * 3) + 1` and `2 * (3 + 1)` and `(const char) *` and `const (char *)`? Oh well. Hopefully someone else does. – user253751 Mar 26 '19 at 22:28
  • From your answer: `const char *` is interpreted as `(const char) *` **i.e. a pointer to a const char**. But const pstring is the same as `const (char *)` **i.e. a pointer to a constant char**. How can they both mean pointer to a constant char? @immibis – Navjot Singh Mar 26 '19 at 22:32
  • @RobertHarvey I think it's a good analogy. You can't split an expression and its sub-expressions into its tokens and then inspect arbitrary groups of them to determine the result. – Max Langhof Mar 26 '19 at 22:54
  • @MaxLanghof: But it's not an *expression* at all; it's a *declaration.* – Robert Harvey Mar 26 '19 at 23:17
  • 1
    @RobertHarvey They are both sequences of tokens that represent things. In both cases a thing represented by a sequence of tokens may be given a name which is also a token. You can't split a token-sequence and its sub-token-sequences into its tokens and then inspect arbitrary groups of them to determine the result. It doesn't matter which words you use - the abstract concept is the same and is equally valid. – user253751 Mar 27 '19 at 00:53