void 형 포인터에서 ((char *)pv)++ 이 맞나요, (char *)pv++ 이
글쓴이: yangam / 작성시간: 수, 2004/08/11 - 11:05오후
void *pv; char *ps, s[] = "ABCDEFG"; ps = s; pv = ps; ((char *)pv)++ // warning: use of cast expressions as lvalues is deprecated 발생 (char *)pv++ // 어떤 경고 메세지도 없이 잘 동작함
이 일부의 소스는 터보 C 정복 639 페이지에 나온 책의 예제인데요..
분명히 책에서는 첫번째인 ((char *)pv)++ 로 해야된다고 하던데...
실제로 해보니, 동작은 제대로 되지만 경고가 발생하네요.
저자분이 실수하신건가요?
컴파일러는 gcc version 3.3.3 20040412 (Red Hat Linux 3.3.3-7) 입니다.
답변 부탁드려요;;
(char *)pv++ 이 맞는건지, 아니면 ((char *)pv)++ 이 맞는건지....
근데, 연산자 순위대로 해석하자면 2 개가 어떻게 다르게 되는거죠?
괄호가 가장 높은 연산 순위를 갖으므로.. (char *) 로 pv 를 형변환 한 후에
pv의 주소 값을 1 * sizeof(char) 만큼 증가시키는 것으로 같은것 아닌가요?
분명히, 아닌 것 같은데... ;;;;
답변 부탁드립니다.
Forums:
pv++;만 하면 pv값이 1올라갑니다.(char*)pv++;는p
pv++;만 하면 pv값이 1올라갑니다.
(char*)pv++;는
printf("%s", (char *)pv++); 이런 정도로 쓰이겠죠.
제 생각에는...
(char*)p++ 이것은 (char*)(p++) 과 같습니다.
p 가 void* 이므로 size 정보를 알수가 없으므로 이건 절대 될수가 없다고 봅니다.
그리고
((char*)p)++ 이부분은 언뜻보기에는 정확한 표현 처럼 보이지만....
((char*)p) 이 표현자체가 r-value 를 뜻하고 있습니다.
Re: void 형 포인터에서 ((char *)pv)++ 이 맞나요, (char *)pv+
"터보 C 정복"이 포인터에 대해서라면 아주 훌륭한 책이지만, C 언어 표준을 익힌다거나 C 문법을 익히는 데에도 좋은 책은 아닙니다.
"터보 C"라는 특정 구현에서 잘 돌아가는 방법이 나와있습니다만, 그게 부작용)side effect)에 의한 것일 수도, 아니면 나름대로의 구현에 의한 것인지가 구분되어 있지 않습니다.
옥과 티를 골라가며 읽어야 할 책입니다.
Re: void 형 포인터에서 ((char *)pv)++ 이 맞나요, (char *)pv+
((char *)pv)++ 이 맞는데
(char *)pv++이 틀렸는데..
----------------------------------------------------------------------------
[quote](char*)p++ 이것은 (char*)(p++) 과
제가 잘 몰라서 그렀습니다만....
우선 포인터형의 크기는 모두 같은것 아닌가요?
void * a 나 int *b 나 typedef struct a{} * c 나 다 똑같은 싸이즈 아닌가요?
적어도 포인터 연산에서는 결과는 맞게될듯 한데요?
그리고 ((char*)p) 이 표현 자체가 왜 r-value죠 <- 이 질문 하려고 끼어들었었습니다. :oops:
제가 알기론 r-value는 임시적인 값이나 고정된 상수의 의미로 알고 있는데
저건 분명히 왼쪽 항에 대입되어도 되는 식인거 아닙니까?
예를 들어
이것이 틀린것인가요? :oops:
C++, 그리고 C++....
죽어도 C++
[quote]우선 포인터형의 크기는 모두 같은것 아닌가요? voi
아마도 잠시 혼동하신것 같습니다만..
포인터 형의 크기는 다 같지만,
" 포인터++ " 의 형태는
해당 포인터의 크기만큼이 아닌
포인터가 가리키는 type의 사이즈만큼
포인터 값을 증가시키라는 의미입니다.
그러므로 가리키는 type의 크기를 반드시 알아야 되죠.
char * pa; ==> pa++은 1byte증가
int * pi; ==> pi++은 4bye 증가
저도 궁금합니다 ^^
참고로 플그램 돌려봤더니 lvalue가 아닌것은 확실합니다만..
그 원리를 아시는 분은 답변 부탁드립니다.
아앗 너무 부끄럽습니다 ^^[quote]아마도 잠시 혼동하신것
아앗 너무 부끄럽습니다 ^^
실수라고 하기엔 너무 큰 무지군요 ㅎㅎ
이래서 게시판에서 이상한 답글 이야기가 나오는 거네요 ㅠ.ㅜ
ㅎㅎ 왜 그랬을까? 내가?
C++, 그리고 C++....
죽어도 C++
캐스팅의 결과는...
캐스팅의 결과는 값입니다.
회사에서 인터넷 사용을 감시하는지라 길게 적지 못해 죄송합니다.
((char *)pv)++c 표준에서는 올바른 문법이 아니지만 c++
((char *)pv)++
c 표준에서는 올바른 문법이 아니지만 c++에서는 표준에 맞습니다.
gcc에서는 c++과 동일한 식으로 동작합니다.
(char *)pv++
c, c++ 표준에서는 지원하지않은 형식입니다.
gcc 확장입니다. void *를 ++과같은 것을 만났을때 char *와 같이
취급해줍니다.
C99에 보면 footnote 에 다음과 같은 부분이 있습니다.A c
C99에 보면 footnote 에 다음과 같은 부분이 있습니다.
A cast does not yield an lvalue.
casting을 다른 타입으로 하면 그 값이 lvalue가 되면 타입의 alignment라든지 type의 표현 방식과 같은 부분에 제약이 많이 생길겁니다.
위와 같은 표현에서 원래의 타입과 똑같은 char*로 변환을 했지만 그렇지 않고 alignment가 더 엄격한 타입으로 변환을 한다던지 하면 문제가 발생할 수 있습니다.
맞는 표현은 pv = (char*)pv + 1; 이 되겠지요
CD2 입니다.
5.4 Explicit type conversion (cast notation) [expr.cast]
1 The result of the expression (T) cast-expression is of type T. The
result is an lvalue if T is a reference type, otherwise the result is
an rvalue. [Note: if T is a non-class type that is cv-qualified, the
cv-qualifiers are ignored when determining the type of the resulting
rvalue; see _basic.lval_. ]
C++ 참조형인 경우에만 L-value가 될 수 있다고 하는군요.
http://www.itga.com.au/~gnb/wp/cd2/index.html
((char*)pv)++와 (char*)pv++ 둘 다
VC7에서는 Compile Error가 발생합니다.
C++라면 ((char*&)pv)++로 하시면 됩니다.
C++라도 (char*&)pv++는 여전히 문제가 됩니다.
후위 인크리먼트가 먼저 호출되고 캐스트문이 실행 적용되기 때문에 인크리먼트에서 얼마를 증가시켜야 되는지 몰라 거기에서 에러를 발생시킵니다.
___________________________________
Less is More (Robert Browning)
[quote="ixevexi"]우선 포인터형의 크기는 모두 같은것 아닌가
동일한 환경도 동일하지 않는 환경도 있습니다.
- 죠커's blog / HanIRC:#CN
[quote="CN"][quote="ixevexi"]우선 포인터형의 크기
혹시 과거의 far pointer 를 말씀하시는 것인가요?
---
http://coolengineer.com
감사합니다
많이 배우네요.. 감사합니다
작은 것들, 사소한 것들을 소중히 여기고,
항상 최선을 다하는 멋진 사람이 되고 싶다.
그들이 나에게 일깨워준 것처럼,
그들 자신이 얼마나 소중한 존재인지 알 수 있도록
도와주는 그런 좋은 사람이 되고 싶다
댓글 달기