(현) 리터럴의 범위
문자열 리터럴이 함수 밖에서 정의되지 않을까 걱정되기 때문에 저는 항상 문자열 리터럴을 반환하지 않으려고 노력합니다.하지만 저는 이게 사실인지 잘 모르겠어요.예를 들어 다음과 같은 함수를 사용해 보겠습니다.
const char *
return_a_string(void)
{
return "blah";
}
이것이 정확한 코드입니까?저에게는 효과가 있지만, 제 컴파일러(gcc)에만 효과가 있을지도 모릅니다.따라서 문제는 (현) 리터럴이 범위를 가지고 있는가, 아니면 항상 존재하는가 하는 것입니다.
이 코드는 모든 플랫폼에서 괜찮습니다.문자열은 정적 문자열 리터럴로 이진으로 컴파일됩니다.예를 들어 창에 있는 경우 메모장으로 .exe를 열고 문자열 자체를 검색할 수도 있습니다.
정적 문자열이기 때문에 문자 범위는 상관 없습니다.
문자열 풀링:
한 가지 주의해야 할 점은 어떤 경우에는 동일한 문자열 리터럴을 "풀링"하여 실행 파일의 공간을 절약할 수 있다는 것입니다.이 경우 동일한 각 문자열 리터럴은 동일한 메모리 주소를 가질 수 있습니다.그렇다고 해서 그럴 것인지 아닐 것인지 절대로 생각해서는 안 됩니다.
대부분의 컴파일러에서는 streng 리터럴에 정적 문자열 풀링을 사용할지 여부를 설정할 수 있습니다.
문자열 리터럴의 최대 크기:
몇몇 컴파일러는 문자열 리터럴의 최대 크기를 갖습니다.예를 들어 VC++의 경우 약 2,048바이트입니다.
문자열 리터럴을 수정하면 정의되지 않은 동작이 나타납니다.
문자열 리터럴을 수정하면 안 됩니다.이것은 정의되지 않은 동작을(를)
char * sz = "this is a test";
sz[0] = 'T'; //<--- undefined results
넓은 문자열 리터럴:
위의 내용은 모두 넓은 문자열 리터럴에 동일하게 적용됩니다.
예: L "이것은 넓은 문자열 리터럴입니다";
C++ 표준 상태: (섹션 lex.string)
1 문자열 리터럴은 큰따옴표로 둘러싸인 문자(lex.ccon 정의)의 시퀀스이며, 선택적으로 "..." 또는 "L"..."과 같이 문자 L로 시작합니다. L로 시작하지 않는 문자열 리터럴은 좁은 문자열 리터럴이라고도 하는 일반 문자열 리터럴입니다.일반적인 문자열 리터럴은 "n constchar의 배열"과 정적 저장 기간(basic.stc)을 갖는데, 여기서 n은 아래 정의된 문자열의 크기이며, 주어진 문자로 초기화됩니다.L "asdf"와 같이 L로 시작하는 문자열 리터럴은 넓은 문자열 리터럴입니다.넓은 문자열 리터럴은 "array of n const wchar_t" 유형을 가지며 정적 저장 지속 시간을 갖습니다. 여기서 n은 아래 정의된 문자열의 크기이며 주어진 문자로 초기화됩니다.
2 모든 문자열 리터럴이 구별되는지(즉, 중복되지 않는 객체에 저장되는지)는 구현 정의됩니다.문자열 리터럴을 수정하려는 경우의 효과는 정의되지 않았습니다.
당신의 혼란이 어느 정도 명확해지도록 예를 들어보겠습니다.
char *f()
{
char a[]="SUMIT";
return a;
}
안 될 겁니다.
그렇지만
char *f()
{
char *a="SUMIT";
return a;
}
이 일은 통합니다.
이유:"SUMIT"
는 전역 범위를 갖는 리터럴입니다.단지 일련의 문자들인 배열이{'S','U','M','I',"T''\0'}
제한된 범위를 가지며 프로그램이 반환되는 즉시 사라집니다.
이것은 다른 사람들이 설명한 것처럼 C(또는 C++)에서 유효합니다.
주의해야 할 한 가지는 dll을 사용하는 경우 이 코드가 포함된 dll이 언로드되면 포인터가 유효하지 않다는 것입니다.
C(또는 C++) 표준은 런타임 시 로드 및 언로딩 코드를 이해하거나 고려하지 않으므로 구현 정의 결과에 직면하게 됩니다. 이 경우 정적 저장 기간을 가져야 하는 문자열 리터럴은는 호출 코드의 POV에서 프로그램의 전체 기간 동안 지속되지 않도록 나타납니다.
네, 괜찮습니다.그들은 세계적인 현탁 안에서 삽니다.
아니요, 문자열 리터럴에는 범위가 없으므로 코드는 모든 플랫폼과 컴파일러에서 작동합니다.프로그램의 이진 이미지에 저장되므로 언제든지 액세스할 수 있습니다.그러나, 그들에게 편지를 쓰려고 노력하는 것은 (그들을 버림으로써)const
)이(가) 정의되지 않은 동작으로 이어집니다.
실제로 프로그램을 로드할 때 로드되는 영역인 실행 파일의 데이터 섹션에 저장된 제로 종료 문자열에 포인터를 반환합니다.캐릭터를 바꾸려고 하는 것을 피하세요. 예상치 못한 결과를 초래할 수도 있으니까요.
브라이언이 언급한 정의되지 않은 결과에 주목하는 것이 정말 중요합니다.이 함수를 성소수자 * 형식으로 반환하는 것으로 선언했으므로 괜찮을 것입니다. 그러나 많은 플랫폼에서 문자열 리터럴은 실행 파일(일반적으로 텍스트 세그먼트)의 읽기 전용 세그먼트에 배치되며 이를 수정하면 대부분의 플랫폼에서 액세스 위반이 발생합니다.
언급URL : https://stackoverflow.com/questions/267114/scope-of-string-literals
'programing' 카테고리의 다른 글
MariaDB 10에서 Persona Mysql 5.7로 마이그레이션하는 것을 좋아하십니까?업그레이드하는 가장 좋은 방법은 무엇입니까? (0) | 2023.10.01 |
---|---|
JSF, 구성 요소를 주기적으로 ajax로 새로 고침? (0) | 2023.10.01 |
Oracle은 오류 발생 시 트랜잭션을 롤백합니까? (0) | 2023.10.01 |
시스템의 대안.웹.보안.회원가입.aspnetcore에서 암호 생성(netcore app1.0) (0) | 2023.10.01 |
잘못된 사용 부작용 연산자 함수 내에 삽입 (0) | 2023.10.01 |