const 에 대하여...
글쓴이: toy / 작성시간: 토, 2004/02/14 - 3:25오후
gcc에서 const 형에 대하여 이상한점이 있어서 질문합니다.
const char * c1 = "AAAA" ;
일때 c1 = "XXX" ; 는 허용되고 c1[0] = 'O' ; 와 같은건 안되는걸 확인했는데요.
char * const c2 = "BBB" ;
일경우!!!
c2 = "XXX" ; 하면 컴파일할때 워닝한번 나고 실행하면 잘실행됩니다.
c[0] = 'O' ; 는 컴파일할때 워닝안나는데 실행할때 세그폴트나는군요..ㅠㅜ
제가 알기로
c2 = "XXX" 는 허용이 안되고 c[0] = 'O'는 허용되어야하는거 아닌가요??
조언부탁드립니다...
아니면..gcc의 특성인지요...
Forums:
세그폴트가 나는것이 정확한 동작입니다.const char * c1
세그폴트가 나는것이 정확한 동작입니다.
const char * c1 = "AAAA" ;
char * const c2 = "BBB" ;
위와 같이 정의를 한경우에는
c1과 c2의 const 특성과 상관없이
두 포인터가 가르키는 주소가 c1[0]='O'와 같이 쓰기가 가능한 메모리가 아니기 때문에 세그폴트가 나야지 정상입니다 :)
답변감사합니다..^^몇가지 더 궁금한게 있는데요..char *
답변감사합니다..^^
몇가지 더 궁금한게 있는데요..
char * a = "Hello"
char a[] = "Hello"
이둘의 정확한 차이가 어떻게 되는지 갑자기 헛갈리네요..
예전엔 알았던거같은데...
아무튼 배열로 했을때는 값이 변경 가능하더군요.
그런데 .s파일을 보니 둘다 .rodata에 문자열을 넣고있던데요...
그리고요...
char * const a = "hello" 는 a라는 포인터변수값자체를 변경할수없다는것아닌가요...?
그런데 a = "xxx" 이와같은 표현식이 가능하다는게 이해가 잘 안갑니다.
(물론 컴파일할때 워닝은 냈지만 실행할때 잘실행이 되더군요. ) :oops:
...
...
char * const a = "hello";와char *
char * const a = "hello";
와
char * const a;
a = "hello;
는 다릅니다. 제 능력으로 이거 설명하려면 한참 돌아가야 하겠는데요 :roll:
...
...
[quote="akbar"][quote="pyj200"]char * co
저는 "그런데 a = "xxx" 이와같은 표현식이 가능하다는게 이해가 잘 안갑니다."
에 대한 답을 한거였습니다. 8) 위에것을 아래것처럼 착각해서 값을 바꿀 수 있는 것이라고 혼동하면 안된다는 뜻으로 쓴겁니다 :roll:
[quote="pyj200"]char * const a = "hello"
그냥... '기본 값'과 '값의 변경'의 차이 아닌가요?
그리고 const는 값의 변경을 막는다... 정도로 알면 될 것 같은데... ;;
[quote="pyj200"][quote="akbar"]char *
아 그러셨군요. 이런 민망할 때가 ... ^^
답변해주신 모든분들 감사드립니다. ^^[quote="akbar"]
답변해주신 모든분들 감사드립니다. ^^
문자열의 갯수를 20개정도로 해보니 조금 이해가 가네요...배열일경우
문자열의 갯수를 20개정도로 해보니 조금 이해가 가네요...
배열일경우는 rep movsb 를 통해서 스택으로 카피를 해주는데
포인터일 경우는 그런작업이 없군요...
아직 조금은 꺼림직하지만 약간은 이해되네요...^^
감사^^
Re: const 에 대하여...
const char *c1은 c1이 가리키는 개체가 const char형이라는 뜻입니다. 즉 변경 불가능이죠. c1 자체는 변경 가능합니다.
반대로 char* const c2는 c2 자체가 const 라는 뜻입니다. c2 자체의 값은 변경 불가능이지만 c2가 가리키는 개체는 변경 가능합니다.
그럼 다음의 예제에서는 왜 상황이 약간 다른고 하니...
char s[] = "ABC"와 같이 char형 배열의 초기화에 쓰이는 것을 제외하고(이때는 정적 기억 수명을 가지는 개체가 따로 생성되지 않으며, s 안에 그냥 "ABC"가 저장됩니다), 모든 문자열 상수는 그 자신의 첫번째 원소를 가리키는 포인터 주소값과 동일하게 처리됩니다. 그리고 그 자신은 정적 기억 수명을 갖는 const char형 배열이 됩니다.
예제 3으로 돌아가겠습니다. 2번째 코드는 그렇다고 쳐도 왜 3번째와 4번째 줄이 틀린가 하면 그것은 c2 자체는 char * const형이지만 c2가 가리키는 개체, 즉 문자열 상수의 타입이 const char[] 이기 때문입니다.
참고로 예제 3번의 첫번째 줄은 다음과 같이 쓰는 쪽이 더 바람직합니다.
이로써 c1 자체도 변경이 불가능하고, c1이 가리키는 개체도 변경이 불가능하다는 것이 명확해졌습니다.
Re: const 에 대하여...
이것은 C++에 해당하는 것 같습니다.
C++에선 문자열 상수가 const로 묵인되죠.
Re: const 에 대하여...
말씀하시고자 하는 바를 모르겠습니다. C에서는 문자열 상수가 수정될 수 있다는 뜻입니까? 아니면 다른 뜻이 있습니까? 자세한 설명 부탁드립니다.
ps. 다시 한번 문서를 찾아보니 문자열 상수는 char형 배열이고, 그것을 수정하려는 행동의 결과는 정의되어 있지 않다고 나와 있군요. 따라서 엄밀하게 따지자면 const char형 배열이라고 볼 수 없습니다. (문자열 상수의 원소를 변경하려는 행동의 결과는 정의되어 있지 않지만, const char형 배열의 원소를 변경하려는 시도는 금지되어 있습니다) 하지만 무슨 뜻으로 말씀하셨는지에 대해서는 확답을 듣고 싶습니다. 제가 뭔가 잘못 알고 있는 것이 있는지 확인하고 싶군요.
ps2. 좀 더 찾아보니 pointer to pointer to char와 pointer to pointer to const char 사이의 관계에서 문제가 생길 소지가 있군요. 지금까지 문자열상수를 가리킬 때 const char *를 즐겨 사용해 왔는데 char *로 바꿔야 할 것 같습니다.
In The C++ programming langauge SE p.90
뱐 아자씨 말쌈이
간략히 말하면 C++의 리터럴은 const char*지만 C와 옛 버전의 C++은
char*다. 그 옛버전과 수정없는 호환을 위해서 /const와 비 const는 캐스트를 해줘야 합니다 ^^/ char*로 어자인될 수 있게 해놨다...
그리고 뒤에는 char *라고 해서 고칠 수 없고 이때의 에러는 보통 런타임전까지 잡아낼 수 없고, 또한 이 룰에따른 구현은 다를 수 있다. 라고 이야기하네요
그런데 좋은 컴파일러들은 알려줄 수 있지 않을까요? 하다못해 워닝이라두 ^^
PS한번 고쳤습니다. 런타임시에 =>런타임 전까지 ^^
그리고 const 를 비 const포인터로 받으려면
비 const 포인터로 캐스트해야하는 것이 맞죠?
저도 역시 초보라서 잘 몰라서요 고수들의 정확한 답변 부탁드립니다.
C++, 그리고 C++....
죽어도 C++
Re: const 에 대하여...
전 C에서 char *s = "ABC"와 같이 선언 됐을 때 문자열 상수가 변경될 수도
있다는 뜻이였습니다.
전 language lawyer는 아닙니다. 처음엔 implementation 상 점검이였다고
말하고 싶습니다.
제가 이렇게 생각한 것은
와 같은 코드가 전혀 문제가 없다는 것입니다.
ms compiler에서는 run time error도 나지 않더군요.
(Version 13.10.3077 for 80x86)
그리고 엄밀히 하면
과 같이 되어야 합니다.
결과적으로 implementation defined 된 부분이니 C에서 틀린 부분은
없지요.
Re: const 에 대하여...
반면에 gcc 3.2.3에서는 실행시간에 Segmentation fault 가 일어납니다. 지금 옆에 책이 없어서 확인이 불가능한데, 리눅스 쪽에서는 문자열 상수를 별도의 독립된 메모리 구역에 저장한다고 들었던 것 같습니다. 당연히 이 공간에는 수정이 금지되겠지요.
C99를 기준으로 말씀드리자면...
우선, 두개의 동일한 내용을 갖는 문자열 상수가 동일한 것인지 아닌지부터가 벌써 unspecified behavior 입니다.
MSDN에서는 이에 대해 다음과 같이 말하고 있습니다.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/eleme_23.asp
"Note that the compiler may not store two identical strings at two different addresses."
그리고 문자열 상수의 내용을 수정하려는 행위에 대해서는 정의된 바 없습니다. (If the program attempts to modify such an array, the behavior is
undefined.) 따라서 그냥 실행하던 컴퓨터를 말아먹던 컴파일러 마음입니다.
MSDN에서도 이 사항에 대해서는 '그렇게 디자인하지 말라'고 말하고 있습니다.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/eleme_23.asp
In translation phase 6, the multibyte-character sequences specified by any sequence of adjacent string literals or adjacent wide-string literals are concatenated into a single multibyte-character sequence. Therefore, do not design programs to allow modification of string literals during execution. The ANSI C standard specifies that the result of modifying a string is undefined.
댓글 달기