이 한줄 잘 이해가 안가네요 ..

binoopang의 이미지


pages[0] = *(void **) &(int[2]){0,PAGE_SIZE};

pages[0]은 pages 구조체 배열중 하나입니다.
저렇게 해서 어떻게 구조체 값이 넘어가는지 궁금해요 .. 포인터가 많아지니까
해깔려요 ㅠ

wsmrdo의 이미지

저도 헥깔리네요 ㅋ

대충 보면.

(void **) <-- 요건 형변환 연산자..
예를 들어 int *a;
라면 a 번지의 값이 int 형이란 것이죠.
결론 : a는 포인터.

int ** a ;

라면 a번지의 값이 포인터이고 그 포인터 내부의 값이 int형이죠.
결론 a 는 포인터의 포인터.

(void **) &(int[2]) <-- int[2]의 번지(&(int[2]))가. 포인터의 포인터.
따라서 int[2] <-- 포인터가 되죠.

여기서 맨 앞에 * 포인터 연산자가 있으니.
결론은 int[2] 번지의 값 이란 말이네요.

{} 가 붙은 것은 배열 인거 같은데.... 흠..
결론은 pages[0] 를 {0,PAGE_SIZE} 로 초기화 한 것으로 보이는 군요.

음.... 우째 대답이 궁색하네... 재미난 코드군요... 허허.

테스트 해봐야 알겠다는..... 쩝.

wsmrdo의 이미지


뒤에 무언가 붙으면 우선순위때문에 달라집니다.
{} 를 배제하면

*(void **) &(kkk[2]); ==> (void *) kkk[2]
와 같습니다.

복잡하게 표현하는건 복잡해 보이지만 보다 명확하다는 것입니다.
함수 포인터 등에서 쓰이는 형식 같은데. 이때에도 {} 아니라 () 를 사용하는데....

한줄 가지고 모르겠군요.

1. int 를 변수가 됩니까?
2. {} <-- 이거 문제 없습니까?

결론 : 그 한줄이 동작은 하는 거 맞나요.

컴파일러 어디에서 그렇게 썼다는 말인가요.

ipoemi의 이미지

#include
#define PAGE_SIZE 8

int main()
{
void** a=*(void**)&(int[2]){0,PAGE_SIZE};
void** b=*(void**)&(int[2]){PAGE_SIZE,0};
printf("%x, %x\n",a,b);
return 0;
}

결과 :
0, 8

이네요...

wsmrdo의 이미지

#include
#define PAGE_SIZE 8

int main()
{
void** a=*(void**)&(int[2]){0,PAGE_SIZE};
void** b=*(void**)&(int[2]){PAGE_SIZE,0};
printf("%x, %x\n",a,b);
return 0;
}

VC++ 6에서 에러납니다. ㅡ.ㅡ;;

D:\VCprg\Study\mytest7\testcpp.cpp(6) : error C2059: syntax error : '{'
D:\VCprg\Study\mytest7\testcpp.cpp(6) : error C2143: syntax error : missing ';' before '{'
D:\VCprg\Study\mytest7\testcpp.cpp(6) : error C2143: syntax error : missing ';' before '}'
D:\VCprg\Study\mytest7\testcpp.cpp(7) : error C2059: syntax error : '{'
D:\VCprg\Study\mytest7\testcpp.cpp(7) : error C2143: syntax error : missing ';' before '{'
D:\VCprg\Study\mytest7\testcpp.cpp(7) : error C2143: syntax error : missing ';' before '}'
Error executing cl.exe.

뭐 어떻든.

int[2] <-- int형 메모리 두개 할당. 이군요.
{0,PAGE_SIZE} <-- 거기에 들어갈 초기화 데이터.

(void **) <-- 형변환 연산자 포인터의 포인터.
&(int[2]) <-- 준비한 배열의 주소.
* 그것의 값이군요.

배열주소는 배열[0]을 가리키고 있죠.
a[0] == *a

그래서 배열의 첫번째 데이터가 변수에 들어갑니다.

이상이네요.

결론은 int 형 배열 공간 2개 에 { } 의 값을 넣고.
그 첫번째 배열원소의 값을 변수에 넣은 겁니다.

해석은 맞는 거 같은데. VC++에서 에러납니다. 컴파일러는 gcc인가요?

ipoemi의 이미지

gcc 4.1.3 입니다

grassman의 이미지

좀 트릭이 들어간 것 같은데요. int와 void *의 크기 차이가 정확히 2배일 경우에는
{0,PAGE_SIZE}의 값이 구조체로 한번에 복사될 수 있을겁니다. 하지만 그렇지 않고
크기가 같을 경우 {0,PAGE_SIZE} 중 0 값만 복사될 겁니다. 결론적으로 CPU와 (경우에
따라서는) 컴파일러에(도) 매우 의존적인 코드입니다.

해석은 거꾸로 하면 됩니다. {0,PAGE_SIZE}는 두개의 int 값을 갖는 배열입니다.
그 다음 이것을 굳이 (int[2])로 type casting 해 주어 int 2개의 배열임을 명시한
것입니다. C언어는 배열의 크기에 신경쓰지 않으므로 (int[])로 해 줘도 결과는
동일합니다. 그리고 배열의 처음 주소를 & 연산자로 구합니다. 여기까지 하면
배열에 대한 pointer를 구한 것이 됩니다. 따라서 (void **)로 type cast를 해
준 뒤 그 pointer가 참조하는 void *값을 * 연산자를 통해 구한 것입니다. 결국
int 2개의 배열이 void *로 타입 변환되고 void * 값으로 해석된 것입니다.

binoopang의 이미지

많은 도움이 되었습니다
답변주신분들 감사합니다 ^^*
-------- 시그내쳐 ---------
열심히 열심히 열심히 .. 다
음악을 하는것 처럼!!

-------- 시그내쳐 ---------
열심히 열심히 열심히 ..
음악을 하는것 처럼!!

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.