"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-битных платформах).