2012-12-13 7 views
1

다음 코드는 두 가지 기능을 썼습니다. 두 가지 모두 동일한 출력을 생성하기위한 것입니다. 그러나 루프가있는 함수 g()은 아래에 표시된 것으로 예상했던 것과 다른 출력을 생성합니다.복합 리터럴은이 코드에서 어떻게 작동합니까?

#include <stdio.h> 

struct S { int i; }; 

void f(void) 
{ 
    struct S *p; 

    int i = 0; 

    p = &((struct S) {i}); 
    printf("%p\n", p); 

    i++; 

    p = &((struct S) {i}); 
    printf("%p\n", p); 
} 

void g(void) 
{ 
    struct S *p; 

    for (int i = 0; i < 2; i++) 
    { 
     p = &((struct S) {i}); 
     printf("%p\n", p); 
    } 
} 

int main() 
{ 
    printf("Calling function f()\n"); 
    f(); 

    printf("\nCalling function g()\n"); 
    g(); 
} 

출력 :

Calling function f() 
0023ff20 
0023ff24 

Calling function g() 
0023ff24 
0023ff24 

가 어떻게 호출 할 때 p의 주소 g() 경우에 동일 올?

답변

5

글쎄, 난 당신이 성취하려는 정확히 모르겠지만, 여기에서 발생하는 것은 :

  • C99의 (struct S){i} 표기 스택에 새로운 데이터 구조를 생성한다
  • 이 데이터 구조가보기 자동
  • 012 작성된 범위의 끝에서 소멸

따라서 f() 함수에서 (실제로 동일한 포인터에 주소를 할당하더라도) 전체 함수의 범위에서 실제로 두 개의 구별 된 구조를 만듭니다. 따라서 두 개의 서로 다른 주소가 사용됩니다.

void f(void) 
{ 
    struct S *p; 

    int i = 0; 

    p = &((struct S) {i}); // <- first data structure, let's call it A 
    printf("%p\n", p);  // <- address of the structure A printed 

    i++; 

    p = &((struct S) {i}); // <- second data structure, let's call it B 
    printf("%p\n", p);  // <- address of the structure B printed 
}       // <- both A and B destroyed 

있으나, g() 함수에 p 생성되고 for 블록의 내부 블록 파괴 등 항상 동일한 어드레스를주고, 스택의 같은 위치에 다시 P를 통해 분배되는 것을 일어나고 .

void g(void) 
{ 
    struct S *p; 

    for (int i = 0; i < 2; i++) 
    { 
     p = &((struct S) {i}); // <- data structure A created 
     printf("%p\n", p);  // <- data structure A's address printed 
    }       // <- data structure A destroyed 
} 
+0

'struct()'에 대해 두 개의 로컬 스코프에'f()'를 넣으려고했으나 결과가 바뀌지 않았다. 이상하게 보인다. – Jack

+0

감사합니다. 나는'& ((struct S) {i}) '를 정적 저장소 객체와 어떻게 든 혼동합니다. 나는 무슨 일이 일어나고 있는지 보지 못했습니다. – cpx

2

확실하게 어셈블리 코드를 확인해야하지만 은 자동 할당 변수 (스택에 할당 됨)의 주소가있는 루프 범위에서 로컬로 할당되기 때문에 동일한 공간을 다시 사용합니다 스택

f()에서 두 구조체가 같은 범위에 공존하므로 g() 컴파일러에서 컴파일러는 &((struct S) {0})을 사용할 수 없다고 확신합니다.

그냥 어떤 변화가 있는지 확인하기 위해 gcc4.2에 -O2과 호기심을위한 노력 :

Calling function f() 
0x7fff5fbff388 
0x7fff5fbff380 

Calling function g() 
0x7fff5fbff390 
0x7fff5fbff390 
+0

그냥 '-O2'로 관찰 한 변화가 무엇인가요? 두 개의 다른 주소를주는'f'와 두 개의 동일한 주소를주는'g'가 출력되는 것입니다. –

+0

참으로 변경이 없습니다. 그냥 결과를 지적했다 : – Jack

관련 문제