Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is "const LPVOID" equivalent to "void * const"?

And if so, why some Win32 headers use it?

For instance:

BOOL APIENTRY VerQueryValueA( const LPVOID pBlock,
    LPSTR lpSubBlock,
    LPVOID * lplpBuffer,
    PUINT puLen
    );

A bit more elaboration: If the API never uses references (or any other C++-only constructs) but only pointers and values, what is the point of having const LPVOID vs. LPCVOID.

Should I treat every place I see const LPVOID as some place where the real meaning is LPCVOID? (and thus it is safe to add a cast)

Further clarification: It appears that const LPVOID pBlock was indeed a mistake in this case. Windows 2008 SDK replaces it to LPCVOID in VerQueryValue signature. Wine did so quite some time ago.

like image 228
EFraim Avatar asked Nov 27 '09 12:11

EFraim


1 Answers

A typedef-name denotes a type, and not a sequence of tokens (as does a macro). In your case, LPVOID denotes the type also denoted by the token sequence void *. So the diagram looks like

// [...] is the type entity, which we cannot express directly.
LPVOID => [void *] 

Semantically if you specify the type const LPVOID, you get the following diagram (the brackets around the specifiers mean "the type denoted by the specifier"):

// equivalent (think of "const [int]" and "[int] const"):
const LPVOID <=> LPVOID const =>  const [void *] <=> [void *] const  
                              =>  ["const qualified void-pointer"]

It's not the same thing as the token sequence const void * - because this one would not denote a const qualified pointer type, but rather a pointer to a const qualified type (the thing pointed to would be const).

Syntactically a parameter declaration has the following (simplified) form:

declaration-specifiers declarator

The declaration-specifiers in case of const void *p are const void - so the base-type of *p is a const qualified void, but the pointer itself is not qualified. In case of const LPVOID p however the declaration-specifiers specify a const qualified LPVOID - which means the pointer type itself is qualified, making the parameter declaration identical to void *const p.

like image 157
Johannes Schaub - litb Avatar answered Oct 04 '22 05:10

Johannes Schaub - litb