C에서는 pointer to const char과 pointer to char이 호환이 안되는 듯 하더군요.
어떤 type이 있을 때
type과 const type은 호환이 되지만
pointer to type과 pointer to const type은
안되는듯 합니다.
배열이나 volatile이 붙을 경우에도 마찬가지.
위에줄에서 charr을
array of array of char로 선언했으니까
아래줄의 charr은
pointer to array of char이 될 테고
pcharr은
pointer to array of const char
당근 호환 안되죠
const char (* const pcarr)[5] = charr;
의 경우에도
pcarr은
const pointer to array of const char이 될 테니까
여전히 호환이 안되겠네요.
해결책은
char (* const pcarr)[5] = charr;
이렇게 하면
charr은
pointer to array of char
pcarr은
const pointer to array of char
type과 const type은 호환되니까 OK.
다만 pcarr자체는 const니까 차후 변경이 안되겠네요.
pcarr로 배열에 접근해서 수정하는건 가능해도.
type qualifier는 타입명의 맨 앞에 붙었을때만
서로 호환이 됩니다.
pointer나 array, structure등을 통해
중간에 붙었을 때는
호환되지 않습니다.
: C에서는 pointer to const char과 pointer to char이 호환이 안되는 듯 하더군요.
여기에 대해서 다른 분들께 추가설명이 필요할 것 같군요.
표준의 Conversions -> Pointers 중에 이런 설명이 있습니다.
For any qualifier q, a pointer to a non-q-qualified type may be converted to a pointer to
the q-qualified version of the type; the values stored in the original and converted pointers
shall compare equal.
pointer to const char 에서 pointer to char 로의 변환은 가능한데 그 역은 안됩니다.
두 타입이 서로 compatible type이 아닐꺼라고 생각은 하지만,
확신은 못하겠고 왜 그런지도 설명은 못드리겠습니다.
그러니까 char * 에서 const char * 로의 변환은 가능합니다.
표준의 내용도 그런 이야기이구요.
제 관심은 char (*)[상수] 에서 const char (*)[상수] 가 가능한지를 묻고 있습니다.
즉 pointer to basic type 에서 pointer to const basic type 은 분명 변환이 되지만
basic type 이 아닌 배열이 올 경우 어떻게 되는지가 궁금하네요.
만일 basic type 이 아닌 pointer 가 올 경우 문제가 있을 수 있다는 점은 알고 있습니다.
다시 말해
char ** 에서 const char ** 는 불가능하죠.
pointer to pointer to basic type 에서 pointer to pointer to const basic type 은 불가능하다는 뜻입니다.
C에서는 pointer to const
C에서는 pointer to const char과 pointer to char이 호환이 안되는 듯 하더군요.
어떤 type이 있을 때
type과 const type은 호환이 되지만
pointer to type과 pointer to const type은
안되는듯 합니다.
배열이나 volatile이 붙을 경우에도 마찬가지.
위에줄에서 charr을
array of array of char로 선언했으니까
아래줄의 charr은
pointer to array of char이 될 테고
pcharr은
pointer to array of const char
당근 호환 안되죠
const char (* const pcarr)[5] = charr;
의 경우에도
pcarr은
const pointer to array of const char이 될 테니까
여전히 호환이 안되겠네요.
해결책은
char (* const pcarr)[5] = charr;
이렇게 하면
charr은
pointer to array of char
pcarr은
const pointer to array of char
type과 const type은 호환되니까 OK.
다만 pcarr자체는 const니까 차후 변경이 안되겠네요.
pcarr로 배열에 접근해서 수정하는건 가능해도.
type qualifier는 타입명의 맨 앞에 붙었을때만
서로 호환이 됩니다.
pointer나 array, structure등을 통해
중간에 붙었을 때는
호환되지 않습니다.
머리 빠개지는군요.
제가 원했던 것은 pcarr 을 통해서 배열 member 를 수정할 수 없도록 하기 위함이었는데요.
적절한 대안이 없는 것 같군요.
이중 pointer 에 대한 형한정어가 변환에 미치는 영향은 어찌어찌 이해가 갑니다만
이것은 또 왜이러는지...~
이것이 안되는 이유가 논리적 문제점을 가지고 있어서인지, 아니면 기술적 한계인지 설명해줄 수는 없을까요?
저도 야매로 대충
저도 야매로 대충 배워서 왜 두개가 서로 호환형이 아닌지에 대해 설명드리진 못하겠습니다.
compatible type란 개념에 대해 대충 넘어가서;;;
하지만 무조건 되게 해야하는 거라면 해결책은 제시할 수 있습니다.
char charr[5][5];
void * t = charr;
const char (*pcarr)[5] = t;
말씀하신 대로의 목적 뿐이라면
두 타입 간에 정렬제한 문제가 발생하거나
혹은 const인 객체를 수정하거나 하는 일은 없을 듯하니
아마도... 아마도 별 문제 없을 것 같습니다.
문제 생기면 저 찾지 마세요;;;
그럴바에 아예 casting 을 하거나 warning 나는 대로가 낫지 않을까요?
void * 로 변환후 원래의 형과 호환되지 않는 형으로 돌아오지 않는 것은
표준에 보장되지 않는 방식으로 압니다.
그런 식으로 compiler 의 경고와 오류를 피해갈 바엔 아예 casting 을 하거나
경고가 나는 상태로 쓰는게 나을 것 같습니다.
: C에서는 pointer to
: C에서는 pointer to const char과 pointer to char이 호환이 안되는 듯 하더군요.
여기에 대해서 다른 분들께 추가설명이 필요할 것 같군요.
표준의 Conversions -> Pointers 중에 이런 설명이 있습니다.
For any qualifier q, a pointer to a non-q-qualified type may be converted to a pointer to
the q-qualified version of the type; the values stored in the original and converted pointers
shall compare equal.
pointer to const char 에서 pointer to char 로의 변환은 가능한데 그 역은 안됩니다.
두 타입이 서로 compatible type이 아닐꺼라고 생각은 하지만,
확신은 못하겠고 왜 그런지도 설명은 못드리겠습니다.
제가 C언어의 type에 대한 이해가 변변찮아서 좀 횡설수설합니다. 이해 바랍니다.
오해가 있는 것 같군요.
그러니까 char * 에서 const char * 로의 변환은 가능합니다.
표준의 내용도 그런 이야기이구요.
제 관심은 char (*)[상수] 에서 const char (*)[상수] 가 가능한지를 묻고 있습니다.
즉 pointer to basic type 에서 pointer to const basic type 은 분명 변환이 되지만
basic type 이 아닌 배열이 올 경우 어떻게 되는지가 궁금하네요.
만일 basic type 이 아닌 pointer 가 올 경우 문제가 있을 수 있다는 점은 알고 있습니다.
다시 말해
char ** 에서 const char ** 는 불가능하죠.
pointer to pointer to basic type 에서 pointer to pointer to const basic type 은 불가능하다는 뜻입니다.
이렇게 하면 되지 않을까요?
char charr[5][5];
const char (*pcarr)[5] ={charr[0],charr[1],charr[2],charr[3],charr[4]};
포인터배열이므로 구성원은 포인터가 되어야 할 듯합니다.
const char (*pcarr)[5] = charr;
이것은 포인터배열에 더블포인터를 assign한것이니 호환이 안되겟죠
님이 올린 코드
님이 올린 코드 컴파일해서 확인부터 해보십시오.
winner님이 어설픈 문제갖고 질문올리겠습니까?
님은 복잡한 선언의 해석방법부터 잘못 익히셨습니다.
아니, 그 이전에 배열과 포인터부터 다시 공부하셔야 할 듯 합니다.
이번을 기회로 해서 기초부터 다시 복습하십시오.
강렬한 지원 감사합니다.
다만 저 역시 그다지 대단한 문제를 올린 것은 아닙니다.
harisoo 씨의 글은 과거 저를 떠올리는 부분이 많구요.
예전에 저는 훨씬 졸렬한 글을 올린 적도 많습니다.
검색해보면 많이 나오죠.
답변이 좀 강렬해서 저를 생각해주시는 것은 감사합니다만 반대로 부담감도 조금 오는군요. ^_^
컴파일 환경을 알려주실수 있나요?
char charr[5][5];
const char (*pcarr)[5] = charr;
위 두줄은 VS.Net 2005와 gcc 4.1.2에서 에러없이 정상동작합니다.
컴파일 환경을 알려주실수 있나요?
gcc 4.1.2 와 3.4.2 일겁니다.
Ubuntu 7.04 에 포함된 gcc 4.1.2 와 MinGW 5.1.3 에 포함된 gcc 3.4.2 로 compile 을 했습니다.
물론 compile 은 됩니다만 warning 이 나오죠.
형변환에 좀더 딱딱한 C++ 로 compile 하면 아예 error 가 나죠.
그런가요? 이상하네요
그런가요?
이상하네요. C++에선 깨끗이 컴파일될 텐데요.
따라서 static_cast도 필요없고요.
질문하신 분은 아마 C++로 컴파일하신 듯합니다.
예, 확인했습니다. 제 실수입니다.
error 는 다른 곳에서 난 것이었습니다.
두줄 warning 이 났었는데 C++ 로 바꾸자 똑같이 비호환 변환 문제로
error 가 두 줄이 나와 제가 성급하게 판단했었네요.
캐스팅 해서
캐스팅 해서 변환하면 되지 않나요?
const char (*pcarr)[5] = (const char (*)[5])charr;
물론 error 와 warning 이 사라질 겁니다.
Casting 은 표준이 보장하는 바를 넘어서는 강력한 programmer 의 의지를 보여주는 것이니까요.
C++ 의 경우 static_cast 를 쓰게 되면 어떻게 될지 궁금하군요...
g++ 로 컴파일하면
g++ 로 컴파일하면 위의 코드는 워닝/에러가 나지 않았습니다.
잘못 컴파일 한 건가요? (gcc에서는 워닝 뜹니다.)
$Myoungjin_JEON=@@=qw^rekcaH lreP rehtonA tsuJ^;$|++;{$i=$like=pop@@;unshift@@,$i;$~=18-length$i;print"\r[","~"x abs,(scalar reverse$i),"~"x($~-abs),"]"and select$good,$day,$mate,1/$~for 0..$~,-$~+1..-1;redo}
친절한 capture 감사합니다... ^_^
Compiler 최신이군요. Early adapter 들은 부럽습니다. ^_^
g++ 는 아무 문제가 없다는데 gcc 가 warning 이라는 것은...
gcc 의 문제일까요?... ^_^
추측에
추측에 불과하지만
gcc는 “아마 문제가 될 것이다.” 로 대충 넘어가고
g++는 “문제 있어보이는데.. 더 살펴봤더니 아니다.” 로 짚고 넘어가는게 아닐까요? =_=;;
$Myoungjin_JEON=@@=qw^rekcaH lreP rehtonA tsuJ^;$|++;{$i=$like=pop@@;unshift@@,$i;$~=18-length$i;print"\r[","~"x abs,(scalar reverse$i),"~"x($~-abs),"]"and select$good,$day,$mate,1/$~for 0..$~,-$~+1..-1;redo}
물론 오류 및 경고 message 는 어디까지나
Compiler 의 품질일 뿐 표준의 요구사항은 아닙니다만...
gcc 의 message 는 다음과 같습니다.
warning: passing arg 1 of `함수이름' from incompatible pointer type
may 라는 단어만 넣어줬어도 제가 의심하지는 않을텐데 말이죠.
int main() { char
int main()
{
char charr[5][5];
char (*pcarr)[5] = charr;
pcarr[0][0] = 20;
printf("%d\n", charr[0][0]);
return 0;
}
ubuntu 7.04
gcc는 4.02입니다..
shell: gcc -W -Wall -o test test.c
./test 결과 20입니다;; 문제 없는 코드 아닌가요..(전 const는 안썻지만요..)
(warning도 없습니다.)
아무리 생각해도 const
아무리 생각해도 const 때문에 뜨는 warning 같은데요 -_-++
운영자님 밑에 글 2개
운영자님 밑에 글 2개 지워 주세요 -_-++
부탁드립니다;;
const 때문에 에러
const 때문에 에러 나는거 아닌가요;;
const 때문에 나는
const 때문에 나는 warning가 아니면 warning가 안날꺼 같은데요..
winner 님 메일 주소가
winner 님 메일 주소가 어떻게 되시죠?
메일 드리려 했는데 사용자 정보에 메일 주소가 공개되어 있지 않네요... --;
이거 어떻게 써야...
winner at uos ac kr 입니다.
서울시립대 대학원생입니다...
그런데 대게 어떻게 써야 spammer 들한테 안 걸리죠?
메일
메일 보냈습니다.
흠... 메일 주소는... 글쎄요... 저 같은 경우 그냥 @ 정도만 at 으로
대체해 공개하고 스팸은 필터링에 의존하고 있습니다. 필터링 통과하는
스팸 몇개는 재미삼아 봐주고 있습니다. ^^
좋은 하루 되세요~
이 질문은 완료되었습니다.
익명사용자 분의 e-mail 로 제 궁금증의 대부분이 해결되었습니다.
그럼 다들 즐프~
그 답변이 저도
그 답변이 저도 궁금한데 공개하실 생각 없으세요?
특별히 숨길 이유가 없다면요.
아마도 winner님께
아마도 winner님께 메일을 보낸 사람은
몇몇 유저들이 kldp에서 쫓아낸 그 사람일테고
kldp를 끊겠다는 자신의 맹세를 지키는 것이겠죠.
따라서 이메일 내용이 공개될일은 없겠군요.
저도 내용이 몹시 궁금하긴 합니다만
이메일 내용이 공개되는 일은 없었으면 합니다.
있을때는 박대하더니만 없으니 또 아쉬워들 하는군요.
아마 이메일 내용이 그대로 올라오면
이 쓰레드는 또다시 길고도 복잡한 가지치기를 하게 될 것입니다.
길고도 장황한 설명이 될게 뻔하니
거기에 달리는 답변은 분명
말장난을 통한 주제 흐리기나 글쓰는 스타일에 대한 공격,
혹은 de facto standard 떡밥이 되겠죠.
늘 그랬으니까.
그 사건을 계기로 다른 사람들도 대부분 KLDP의 분위기를 파악하고
잠수를 탄 듯 싶습니다.
누군가가 해답을 제시해 줄 법한 문제인데도
모두들 입을 굳게 닫고 있습니다.
굳이 아쉬우신 분은 winner님께 직접 이메일을 보내 질문해 보시는 것이 어떻습니까?
답을 유즈넷에서 찾았습니다.
http://groups.google.co.kr/group/comp.lang.c/browse_thread/thread/6f2d1a8f790392b/43ee44ca5cdd0fe3?lnk=st&q=incompatible+pointer+type&rnum=6#43ee44ca5cdd0fe3
감사합니다만
알고 있던 내용이었습니다. pointer 를 반복적으로 적용하는 과정에서 const 가 어떤 영향을 주는가하는
문제는 익히 아는 내용이었습니다만 이를 배열에 적용할 때 어떻게 될 것인가가 제 의문이었습니다.
하지만 C compilier 가 표준에 의거하여 char ** 를 const char ** 로 변환을 거절하는 것과
char (*)[상수] 를 const char(*)[상수] 를 거절하는 것은 동일한 과정을 통해서 이루어진다고 합니다.
댓글 달기