오픈소스에 버그를 하나 등록했는데 아래와 같은 Comment를 받았습니다.
"this does not go to the .rodata section in the binary;
use static const char foo[] instead."
이게 무슨 소린가 하고, 확인을 하기 위해 간단한 프로그램을 작성해보았습니다.
### c++
/* file: constchar.cpp
*
* gcc -S -O0 constchar.cpp -DCONST_POINTER
*/
#if defined(CONST_POINTER)
static const char* name = "hello";
#elif defined(CONST_ARRAY)
static const char name[] = "hello";
#else
static const char* const name = "hello";
#endif
int main()
{
return 0;
}
확인해보니 리뷰 comment대로
static const char* name = "Hello"; (이하 const_pointer)와 static const char name[] = "Hello"; (이하 const_array)
static const char* const name = "Hello"; (이하 const_pointer_const)
이 셋이 서로 다른 코드를 생성하는 것을 알 수 있었습니다.
먼저 .text 섹션을 보겠습니다.
main함수가 동일하기 때문에 위치만 다를뿐 동일합니다.
세 경우 모두, .rodata 섹션에 Hello 가 들어있습니다.
하지만 name(_ZL4name) 심볼의 경우,
const_pointer.s의 경우만 .data 섹션에 있고, const_array.s와 const_pointer_const.s의 경우에는 .rodata 섹션에 같이 있습니다.
생각해보면, const_pointer.s는 name의 값을 바꿀 수 있으니 당연히 .data 섹션에 변수로서 존재해야 합니다.
예를 들어 아래는 정상적인 코드입니다. static const char* name = "Hello";
name = "changed"; 하지만 아래는 컴파일 에러가 납니다. static const char name[] = "Hello";
name = "changed"; 따라서 변경 불가능한 문자열을 만들려고 한다면, const char [] 또는 const char* const를 사용해야 합니다.그럼 const_array.s와 const_pointer_const.s의 차이는 뭘까요?
const_array.s를 보시면 LC0 label이 없는 것을 알 수 있습니다.
const_array.s의 경우만 name이 직접 Hello를 가르키고 있습니다.
(결론)
상수형 문자열을 쓰고자 한다면 static const char foo[] = "XXX"; 형태가 낫습니다.
참고로 아래 링크는 C언어의 변수 선언시 저장되는 영역에 관한 것입니다.
http://wwww7.com/bbs/zboard.php?id=Study&page=1&sn1=&divpage=1&category=3&sn=off&ss=on&sc=on&select_arrange=headnum&desc=desc&no=57
'프로그래밍 언어 > C&C++' 카테고리의 다른 글
GCC 옵션 : version script (0) | 2012.08.14 |
---|---|
[C++] new는 null을 return하는가? (1) | 2012.01.17 |
우분투에서 ccache로 컴파일을 빠르게... (0) | 2011.08.31 |
POD vs non POD (0) | 2011.08.07 |
memwatch (0) | 2011.05.24 |