3

The following code doesn't compile for me in visual studio 2012:

//1. Define struct
struct TestList
{
...
};

//2 define a pointer to 1. struct as typedef
typedef TestList * TestListPtr;

//3. use it latter on in the code as follows:
    const TestList* p1 = 0;
    const TestListPtr p2 = p1;

Then, get this compile error:

error C2440: 'initializing' : cannot convert from 'const TestList *' to 'const TestListPtr'

An reason why the above can be considered illegal syntax?

Haven't tried it with other compilers yet.

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
AlexK
  • 46
  • 2
  • 1
    `const TestList*` this is a pointer to a const TestList, `const TestListPtr` this is a const pointer to a TestList. The compiler won't let you go from `const T` to `T` without a `const_cast` (or a C-cast *shudders*) – Borgleader Feb 18 '15 at 19:04
  • 1
    Note: const Testlist* is a mutable pointer with immutable content, const TestlistPtr is a immutable pointer with mutable content. –  Feb 18 '15 at 19:08
  • Some fun reading on this subject: http://www.drdobbs.com/conversationsa-midsummer-nights-madness/184403835 – Fred Larson Feb 18 '15 at 19:21

2 Answers2

7

The compiler is right, all conformant compilers must reject that. The reason is that the declarations group differently:

const TestList * p1 declares p1 to be a pointer to a constant TestList.

const TestListPtr p2 declares p2 to be a constant TestListPtr. TestListPtr is a pointer to (non-constant) TestList. Spelling out p2 without the typedef is this:

TestList * const p2 = p1;
Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
2

This is one place where the syntax of the language is not intuitive.

int const i;

is the same as

const int i;

When you mix pointers, there are four possible options:

int* p1;               // You can modify both p1 and *p1
int const* p2;         // You can modify p2 but not *p2
int* const p3;         // You can not modify p3 but can modify *p3
int const* const p3;   // You can not modify p4 or *p4

Unfortunately, you can write

int const* p2;

as

const int* p2;

also, which is the source of your confusion.

Instead of using

const TestListPtr p2 = p1;

if you use

TestListPtr const p2 = p1;

it is clear which part of p2 is constant. It would be clear that p2 cannot be modified but *p2 can.

R Sahu
  • 204,454
  • 14
  • 159
  • 270