2009-11-27 16 views
10

Y si es así, ¿por qué algunos encabezados de Win32 lo usan?¿Es "const LPVOID" equivalente a "void * const"?

Por ejemplo:

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

Un poco más de elaboración: Si el API nunca utiliza referencias (o cualquier otro C++ - sólo se construye), pero sólo los punteros y valores, lo que es el punto de tener const LPVOID vs. LPCVOID .

¿Debo tratar cada lugar que veo const LPVOID como un lugar donde el significado real es LPCVOID? (y así es seguro agregar un molde)

Más aclaración: Parece que const LPVOID pBlock fue un error en este caso. Windows 2008 SDK lo reemplaza a LPCVOID en VerQueryValue firma. Vino lo hizo hace bastante tiempo.

+1

Escuché que '# define''editar esas cosas, por lo que sería' const void * '. Si son typedefs, sería 'void * const' de hecho. –

+0

@litb: Desafortunadamente estos son typedefs – EFraim

+0

@EFraim, ah veo. Mayúscula maldita :) –

Respuesta

12

un typedef-nombre denota un tipo, y no una secuencia de tokens (como lo hace una macro) En su caso, LPVOID denota el tipo también indicado por la secuencia de token void *. Por lo que el diagrama se parece

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

Semánticamente si se especifica el tipo const LPVOID, se obtiene el siguiente diagrama (los corchetes de los especificadores significan "el tipo denotado por el especificador"):

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

Es no lo mismo que la secuencia de token const void * - porque esto no denotaría un tipo de puntero const calificado, sino más bien un puntero a un tipo const calificado (lo que se señala sería const).

sintácticamente una declaración de parámetros tiene la forma siguiente (simplificada):

declaration-specifiers declarator 

la declaración especificadores en caso de const void *p son const void - por lo que el tipo de base de *p se califica un const void, pero el puntero en sí no está calificado. En el caso de const LPVOID p, sin embargo, los especificadores de declaración especifican un const calificado como LPVOID, lo que significa que el propio tipo de puntero está calificado, haciendo que la declaración del parámetro sea idéntica a void *const p.

+1

Espera, ahora estoy confundido. const void * y void * const NO son lo mismo. – EFraim

+1

@EFraim, el cuadro alrededor de 'void *' significa que es el tipo indicado por 'LPVOID' - no significa que el texto aparezca en la declaración. –

+0

Ah, bien, este diagrama me confundió. – EFraim

0

LPVOID es un puntero genérico, que ya es mucho tiempo igual que el puntero genérico normal (era diferente en las plataformas antiguas de 16 bits).

+1

Lo que está bien, sin embargo, tiene poco que ver con el tema de la pregunta. – EFraim

0
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;" 
Cuestiones relacionadas