Why "const" is needed here: VS C2664
I copy code from MSDN
It says that "In Visual C++ 2005, the compiler now enforces the C++ standard requirements for applying const. The following sample generates C2664."
// C2664d.cpp
// C2664 expected
#include <windows.h>
void func1(LPCSTR &s)
{
}
void func2(LPS开发者_运维问答TR &s)
{
func1(s);
}
int main()
{
return 0;
}
Why do I need to use "const" here?
(Those LPCSTR
/LPSTR
typenames only obfuscate the code. )
The issue you have here can be expressed in the following succinct way
char *p = NULL;
const char *&r = p; // ERROR
This code does not compile for the very same reason your original version does not compile: such reference initialization is illegal in C++. In your example the same initialization is used implicitly in function parameter initialization (when calling func1
from func2
), while in my example it is done explicitly.
The reason it is illegal is pretty much the same the T**
-> const T**
conversion is illegal in C++ (and in C). This is an old FAQ: http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.17.
Basically, if the initialization in my above example were legal, one would be able to continue with the following sequence of operations
const char cc = 0;
r = &cc; // OK. Note: `p` now points to `cc`!
*p = 1; // !!! Attempts to modify `cc` !!!
meaning that it would allow us to break the const-correctness rules without any "hacks", i.e. without using a single cast. This is considered unacceptable in C++ (as well as in C), which is the reason conversions like T **
-> const T **
and initializations like T *&
-> const T *&
are not allowed.
Note also, that just like T**
-> const T* const*
conversion is legal in C++ (see the FAQ entry), the T**
-> const T* const&
initialization is legal as well
char *p = 0;
const char *const &r = p; // OK
In that code sample, C2664 will be generated because the code is attempting to convert a reference to a pointer into a reference to a const pointer. Which are two different things.
Converting to a const reference to a pointer (const LPSTR&) would be allowed.
LPCSTR is defined as "typedef CONST CHAR *LPCST" and LPSTR is defined as "typedef CHAR *LPCST"
As you can see, LPCSTR is const and LPSTR is not, so the two types are different and hence you need const in your context.
精彩评论