You are asking "Why is the compiler interpreting (2) to be the same as (3)?". Well, because in C++ language (as well as in C) they are semantically the same. When you define a typename as
typedef int *IntPtr;
then later the type const IntPtr
will stand for int *const
, not for const int *
. That's just how typedef-names work in C++.
Typedef-names in C++ are not macros. While they do not define new types (just aliases for the existing ones), the resulting aliases are nevertheless "atomic", "monolithic" in a sense that any qualifiers applied to the alias will apply as top-level qualifiers. When you are working with a typedef-name, there's no way to "sneak in" a const qualifier so that it would somehow "descend" to a lower-level portion of the type (int
in your case).
If you insist on using typedef-names, you have no other immediate choice but to provide two different typedef-names, like
typedef int *IntPtr;
typedef const int *ConstIntPtr;
and use ConstIntPtr
when you need a pointer-to-const version of the type.