C ++ 11 표준 (ISO / IEC 14882 : 2011)의 내용은 다음과 § C.1.1
같습니다.
char* p = "abc"; // valid in C, invalid in C++
C ++의 경우 문자열 리터럴에 대한 포인터는 수정하려고하면 충돌이 발생하기 때문에 유해합니다. 그러나 C에서 왜 유효합니까?
C ++ 11도 말합니다 :
char* p = (char*)"abc"; // OK: cast added
즉, 캐스트가 첫 번째 명령문에 추가되면 유효합니다.
캐스트가 C ++에서 두 번째 명령문을 유효하게 만드는 이유는 무엇이며 첫 번째 명령문과 어떻게 다른가요? 여전히 해롭지 않습니까? 그렇다면 표준에서 괜찮다고 말한 이유는 무엇입니까?
답변
C ++ 03까지 첫 번째 예제는 유효했지만 더 이상 사용되지 않는 암시 적 변환을 사용했습니다. 문자열 리터럴은 char const *
내용을 수정할 수 없으므로 정의되지 않은 동작이 발생하지 않기 때문에 유형으로 취급해야합니다 .
C ++ 11부터는 더 이상 사용되지 않는 암시 적 변환이 공식적으로 제거되었으므로 첫 번째 예와 같이 이에 의존하는 코드는 더 이상 컴파일되지 않아야합니다.
암시 적 변환이 제거되었지만 명시 적 변환은 여전히 작동하므로 캐스트를 추가 할 수 있습니다. 나는 할 수 없습니다 , 그러나,이 “고정”코드를 살펴 보자.
코드를 올바르게 수정하려면 포인터 유형을 올바른 유형으로 변경해야합니다.
char const *p = "abc"; // valid and safe in either C or C++.
C ++에서 여전히 허용 된 이유 (아직 C에 있음) : 단순히 암묵적 변환에 의존하는 기존 코드가 많기 때문에 (적어도 공식적인 경고없이) 해당 코드를 깨는 것처럼 분명히 표준위원회에 보였다 나쁜 생각.
답변
역사적 이유로 C에서는 유효합니다. C는 전통적으로 문자열 리터럴의 유형이 char *
아닌 이라고 지정 const char *
했지만 실제로는 수정할 수 없다고 말하여 규정했습니다.
캐스트를 사용할 때 기본적으로 기본 유형 일치 규칙보다 더 잘 알고 있다고 컴파일러에 알리고 할당을 확인합니다.
답변
strdup 을 사용할 수도 있습니다 .
char* p = strdup("abc");