«Const LPVOID» эквивалентен «void * const»? - PullRequest
10 голосов
/ 27 ноября 2009

И если так, то почему некоторые заголовки Win32 используют его?

Например:

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

Немного подробнее: если API никогда не использует ссылки (или любые другие конструкции на C ++ - только), а только указатели и значения, какой смысл иметь const LPVOID против LPCVOID.

Должен ли я относиться к каждому месту, которое я вижу const LPVOID, как к месту, где настоящее значение LPCVOID? (и, таким образом, можно добавить актерский состав)

Дальнейшее уточнение: похоже, что const LPVOID pBlock действительно была ошибкой в ​​этом случае. Windows 2008 SDK заменяет его на LPCVOID в VerQueryValue подписи. Вино сделало это довольно давно.

Ответы [ 4 ]

13 голосов
/ 27 ноября 2009

typedef-name обозначает тип, а не последовательность токенов (как это делает макрос). В вашем случае LPVOID обозначает тип, также обозначаемый последовательностью токенов void *. Таким образом, диаграмма выглядит как

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

Семантически если указать тип const LPVOID, вы получите следующую диаграмму (скобки вокруг спецификаторов означают «тип, обозначаемый спецификатором»):

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

Это не то же самое, что последовательность токенов const void * - потому что этот не будет обозначать тип указателя с константным квалификацией, а скорее указатель на тип с константным спецификацией (вещь, на которую указывает Const).

Синтаксически объявление параметров имеет следующую (упрощенную) форму:

declaration-specifiers declarator

Спецификаторы объявления в случае const void *p равны const void, поэтому базовый тип *p является константным void, но сам указатель не квалифицирован. Однако в случае const LPVOID p спецификаторы объявления задают константное значение LPVOID - это означает, что указывается сам тип указателя, что делает объявление параметра идентичным void *const p.

1 голос
/ 27 ноября 2009

Эти ссылки содержат некоторую информацию, которая облегчает понимание typedef лучше:

http://www.velocityreviews.com/forums/t289888-need-clarification-on-typedef-keyword.html http://www.codeproject.com/KB/cpp/complex_declarations.aspx#typedef

0 голосов
/ 25 мая 2010
void* const x = 0;
x = 0; // this line will not compile - u cannot change x, only what it points to
x->NonConstMethod(); // will compile
const void* y = 0;
y = 0; // this line will compile - u can change y, but not what it points to
y->NonConstMethod(); // will not compile
const void* const z = 0; // u cannot change z or what it points to
// btw, the type of the 'this' pointer is "ClassName* const this;"
0 голосов
/ 27 ноября 2009

LPVOID является далеко универсальным указателем, который уже долгое время совпадает с обычным универсальным указателем (он был другим на старых 16-битных платформах).

...