"Const LPVOID" эквивалентен "void * const"?

И если так, то почему некоторые заголовки 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 ответа

Решение

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 является квалифицированным const void, но сам указатель не квалифицирован. В случае const LPVOID p однако спецификаторы декларации определяют константный LPVOID - это означает, что сам тип указателя квалифицирован, делая объявление параметра идентичным void *const p,

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

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

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;"

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

Другие вопросы по тегам