In good API design, one specifies unchangeable data that’s passed by pointer as const:
void foo( const Stuff* pConstantStuff );
The compiler will guarantee that the "Stuff" pointed to by pConstantStuff is not modified by foo(). This is goodness. Microsoft APIs have a habit of using typedefs for structures, ala:
void foo( const STUFF* pConstantStuff );
In fact, some people even use typedefs for pointers to structures:
typedef Stuff* PSTUFF;
And they write the API like this:
void foo( const PSTUFF pConstantStuff ); // Evil; this does not do what you expect!
That last version is not code you ever want to write! What it seems to promise is not what it actually promises. The compiler interprets it as:
void foo( Stuff* const pConstantStuff ); // weird but technically correct
This version guarantees that the pointer itself cannot be changed by the function. However, the contents of pConstantStuff are no longer constant. The code can change the contents and the compiler will happily oblige! There are two solutions. Solution one is to create a const version of the typedef and use it where appropriate. Here’s how winnt.h does it for strings:
typedef char *LPSTR;
typedef const char* LPCSTR;
The preferable solution is to avoid typedefs for pointer types and use const directly whenever you need it. Use const whenever you possibly can. In return, you get readable code that clearly expresses the intent — and the compiler properly enforces the intent.