2011-04-21 2 views
1

을 내가 MSDN: VS C2664

에서 코드를 복사 그것은 "비주얼 C++ 2005에서 컴파일러는 지금 const를 적용하기위한 C++ 표준 요구 사항을 적용합니다 다음 샘플은 C2664을 생성합니다.."고 말했다

// C2664d.cpp 
// C2664 expected 
#include <windows.h> 

void func1(LPCSTR &s) 
{ 

} 

void func2(LPSTR &s) 
{ 
    func1(s); 
} 

int main() 
{ 
    return 0; 
} 

여기서 "const"를 사용해야하는 이유는 무엇입니까?

+0

컴파일 해 보셨습니까? 오류가 발생 했습니까? 정확히 어디에서 오류가 발생 했습니까? 정확히 뭐라고 했지? –

답변

4

(그 LPCSTR/LPSTR typenames에만 코드를 당황하게.)

당신이 가지고있는 문제는이 코드는 바로 그 같은 이유로 컴파일되지 않습니다

char *p = NULL; 
const char *&r = p; // ERROR 

다음과 같은 간결한 방법으로 표현 될 수 있습니다 원래 버전은 컴파일되지 않습니다. C++에서는 이와 같은 참조 초기화가 잘못되었습니다. 귀하의 예제에서 함수 초기화 (에서 func2로)를 호출 할 때 암시 적으로 동일한 초기화가 사용됩니다. 그러나이 예에서는 명시 적으로 수행됩니다.

불법 인 이유는 C++ (및 C)에서는 T** ->const T**과 거의 같은 변환입니다. 이것은 이전 FAQ입니다 : http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.17. 내 위의 예에서 초기화가 합법적 인 경우

기본적으로, 하나는 우리가 어떤없이 CONST-정확성 규칙을 깰 수있는 것을 의미 작업

const char cc = 0; 
r = &cc; // OK. Note: `p` now points to `cc`! 
*p = 1; // !!! Attempts to modify `cc` !!! 

다음과 같은 순서를 계속 할 수있을 것입니다 "해킹", 즉 단일 캐스트를 사용하지 않고. 이것은 C++뿐만 아니라 C에서 받아 들일 수없는 것으로 간주됩니다. 이는 T ** ->const T **과 같은 변환이고 T *& ->const T *&과 같은 초기화는 허용되지 않습니다.

단지 같은 T**도 참고 -

char *p = 0; 
const char *const &r = p; // OK 
1

코드 샘플에서 포인터가 참조를 const 포인터로 변환하려고 시도하기 때문에 C2664가 생성됩니다. 두 가지가 다릅니다.

포인터에 대한 const 참조 (const LPSTR &) 로의 변환이 허용됩니다.

+2

'LPCSTR'은'char * const'가 아닌'const char *'의 typedef입니다. 그게 당신이 "const 포인터에 대한 참조"를 의미하는 것인지 확실하지 않습니다? –

1

LPCSTR가 "형식 정의 CONST로 정의뿐만 아니라>const T* const& 초기화 법적 ->const T* const* 변환 C에서 법적 ++의 T**은 (는 FAQ 항목을 참조하십시오) CHAR * LPCST "및 LPSTR은"typedef CHAR * LPCST "로 정의됩니다.

위에서 볼 수 있듯이 LPCSTR은 const이며 LPSTR은 아니므로 두 유형이 다르므로 컨텍스트에서 const가 필요합니다.

+0

나는 "typedef"를 놓쳤다, 고마워. – metdos