문자열 리터럴의 형식이 적합한 const char[]임
업데이트: 2007년 11월
이제 문자열 리터럴의 형식은 const char []이며 메모리의 읽기 전용 섹션에 배치됩니다. 해당 메모리를 변경하면 액세스 위반이 발생합니다. /GF를 사용하여 이전 버전에서 컴파일한 코드도 액세스 위반을 발생시킵니다.
다음 샘플은 Visual Studio .NET에서는 컴파일되고 실행되지만 Visual Studio .NET 200에서는 런타임에 실패합니다.
// bc_string_literals_have_proper_type_of_const_char.cpp
// compile with: /c
void f(char *c) {
c[0] = 'Q'; // Now gives run-time access violation
}
int main() {
f("TEST");
}
또한 다음 예제와 같은 코드의 런타임 동작이 변경되었습니다.
// bc_string_literals_have_proper_type_of_const_char2.cpp
#include "stdio.h"
void f(const char *) { // called in Visual Studio .NET 2003
printf_s("in f(const char *)\n");
}
void f(char *) { // called in Visual Studio .NET
printf_s("in f(char *)\n");
}
int main() {
f("TEST");
}
이 오류를 해결하려면 문자열 리터럴이 수정될 함수로는 문자열 리터럴을 전달하지 마십시오.
이러한 방식으로 함수가 오버로드될 때 Visual C++의 현재 버전과 이전 버전에서 유효한 코드의 경우 다음을 수행합니다.
문자열 리터럴을 const char*로 명시적으로 캐스팅합니다.
스택이나 힙에 변수를 정의합니다.
다음 코드는 Visual C++의 Visual Studio .NET 2003 및 Visual Studio .NET 버전에서 유효하며 두 버전에서 모두 액세스 위반을 발생시키지 않습니다.
// bc_string_literals_have_proper_type_of_const_char3.cpp
#include <stdio.h>
void f(const char *psz) {
printf_s("const version\n");
}
void f(char *psz) {
printf_s("version where we modify it\n");
psz[0] = 'x';
}
int main() {
char myStr[] = "TEST";
f((const char*)"TEST");
f(myStr);
}