From: Vincent Fatica on
With these, I can compile, getting no complaint about a function, error(),
declared to take a LPTSTR. (UNICODE and _UNICODE are defined.)

..H: extern const LPWSTR foo;
..CPP const LPWSTR foo=L"bar";

But when I use these,

..H extern LPCWSTR foo;
..CPP LPCWSTR foo=L"bar";

I get

error C2664: 'error' : cannot convert parameter 1 from 'LPCWSTR' to 'LPTSTR'
Conversion loses qualifiers

Why? Aren't "LPCWSTR" and "const LPWSTR" both "const WCHAR*"?

Thanks.
--
- Vince
From: Doug Harrison [MVP] on
On 24 May 2010 19:49:35 -0400, Vincent Fatica <vince(a)blackholespam.net>
wrote:

>With these, I can compile, getting no complaint about a function, error(),
>declared to take a LPTSTR. (UNICODE and _UNICODE are defined.)
>
>.H: extern const LPWSTR foo;
>.CPP const LPWSTR foo=L"bar";
>
>But when I use these,
>
>.H extern LPCWSTR foo;
>.CPP LPCWSTR foo=L"bar";
>
>I get
>
>error C2664: 'error' : cannot convert parameter 1 from 'LPCWSTR' to 'LPTSTR'
>Conversion loses qualifiers
>
>Why? Aren't "LPCWSTR" and "const LPWSTR" both "const WCHAR*"?

Nope. "const LPWSTR" is to LPWSTR as "const int" is to "int", which implies
"LPWSTR const" is the same as "const LPWSTR". It's just the way typedefs
work, and it's a common pitfall when making typedefs for pointer types. You
need to use LPCWSTR, which includes the const in the typedef definition.

Note also that if your function is expecting LPWSTR, it is a mistake to
pass it a string literal unless the function is defined not to modify the
string. (In which case, why isn't it taking LPCWSTR?)

--
Doug Harrison
Visual C++ MVP
From: Vincent Fatica on
On Mon, 24 May 2010 19:05:44 -0500, "Doug Harrison [MVP]" <dsh(a)mvps.org> wrote:

|On 24 May 2010 19:49:35 -0400, Vincent Fatica <vince(a)blackholespam.net>
|wrote:
|
|>With these, I can compile, getting no complaint about a function, error(),
|>declared to take a LPTSTR. (UNICODE and _UNICODE are defined.)
|>
|>.H: extern const LPWSTR foo;
|>.CPP const LPWSTR foo=L"bar";
|>
|>But when I use these,
|>
|>.H extern LPCWSTR foo;
|>.CPP LPCWSTR foo=L"bar";
|>
|>I get
|>
|>error C2664: 'error' : cannot convert parameter 1 from 'LPCWSTR' to 'LPTSTR'
|>Conversion loses qualifiers
|>
|>Why? Aren't "LPCWSTR" and "const LPWSTR" both "const WCHAR*"?
|
|Nope. "const LPWSTR" is to LPWSTR as "const int" is to "int", which implies
|"LPWSTR const" is the same as "const LPWSTR". It's just the way typedefs
|work, and it's a common pitfall when making typedefs for pointer types. You
|need to use LPCWSTR, which includes the const in the typedef definition.

I don't get it. And what does "LPWSTR const" have to do with it?

--
- Vince
From: Igor Tandetnik on
Vincent Fatica <vince(a)blackholespam.net> wrote:
> error C2664: 'error' : cannot convert parameter 1 from 'LPCWSTR' to
> 'LPTSTR' Conversion loses qualifiers
>
> Why? Aren't "LPCWSTR" and "const LPWSTR" both "const WCHAR*"?

No. LPCWSTR is "const WCHAR*" - a non-const pointer to const data. "const LPWSTR" is "WCHAR* const" - a const pointer to non-const data. Your function, by taking LPTSTR, declares that it may modify pointed-to data - that's why it can't accept LPCWSTR (where, again, the data is const).
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925

From: Doug Harrison [MVP] on
On 24 May 2010 20:49:10 -0400, Vincent Fatica <vince(a)blackholespam.net>
wrote:

>I don't get it. And what does "LPWSTR const" have to do with it?

Its equivalence to "const LPWSTR" illustrates that typedefs aren't macros,
and that const doesn't penetrate them. Re-read my first message. All
typedefs "X" are like "int" WRT CV-qualifiers being applied to them.

--
Doug Harrison
Visual C++ MVP