-2

I came across this code in win32 API programming tutorial and I am struggling to understand it.

if (msg == WM_NCCREATE) 
{
    const CREATESTRUCTW* const pCreate = reinterpret_cast<CREATESTRUCTW*>(lParam);
}

What does const CREATESTRUCTW* const pCreate mean?

I did find this answer while doing my research. The example provided in that question was :

const GLvoid* const *indices

and a summary of the accepted answer is:

The correct way to write it is GLvoid const* const* and the correct way to read it is from right to left which reads:

" It is a pointer to a const pointer to a const object of type GLvoid ".

This confused me even more because no matter how I read it, reading it from right to left reads:

" It is a const pointer(const*) to a const pointer(const*) to an object of type GLvoid(GLvoid)".

It would also be nice if anyone could explain it in terms of my question i.e. const CREATESTRUCTW* const pCreate. Thanks.

Apple_Banana
  • 131
  • 6
  • Sometimes declarations could be hard to comprehend. I think using spiral rule can help in decrypting declaration meaning. See "C++/C Spiral Rule", like here http://c-faq.com/decl/spiral.anderson.html – kreuzerkrieg May 23 '21 at 08:49

3 Answers3

3

Let's rewrite this

   const CREATESTRUCTW* const pCreate

into this:

   CREATESTRUCTW const * const pCreate
// <------- a -------> <- b ->

which means the same thing.

const refers to the thing to the left, so you have an immutable pointer (b) that is pointing to an immutable object of type CREATESTRUCTW (a).

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
2

Let's take that apart ...

  • CREATESTRUCTW* pCreate - pCreate is a pointer to an object of type CREATESTRUCTW
  • const CREATESTRUCTW* pCreate - pCreate is a pointer to a const object of type CREATESTRUCTW
  • const CREATESTRUCTW* const pCreate - pCreate itself is const, once a value has been assigned to it, it can't be changed
1

const CREATESTRUCTW* const pCreate

The pointer pCreate is unmodifiable, and the CREATESTRUCTW it points to cannot be modified via pCreate.

That is after declaration:

pCreate = NULL ; // will fail to compile

and also:

pCreate->style = WS_BORDER ; // will also fail to compile

essentially it provides read-only protection for the pointer and for what it points to.

Note that while the CREATESTRUCTW object is unmodifieble via this pointer, it could be modifiable via a non-const pointer to the same object.

const GLvoid* const *indices

Is a const pointer to a const pointer to GLvoid. That is like a GLvoid** but where indices is unmodifieable and *indices is modifiable. The GLvoid object **indices is however modifiable.

The correct way to write it is GLvoid const* const* ...

That is nonsense; that is an alternative, but const GLvoid* const *indices is no less correct, and more idiomatic. Which is easier to understand in a matter of opinion.

Clifford
  • 88,407
  • 13
  • 85
  • 165