2010-01-08 2 views
2

컴파일러에서이 두 문장에 대해 동일한 코드를 생성합니까?참조 스택 프레임 레이아웃에 의한 포인터/인수에 의한 c/C++ 인수 전달

foo1(int* val){(*val)++;} 

foo2(int &val){val++;} 

foo의 스택 프레임의 매개 변수 부분에 포인터를 쓰면됩니까? 또는 두 번째 경우 호출자의 로컬 변수가 스택의 동일한 메모리를 foo의 매개 변수로 사용하도록 호출자와 foos의 스택 프레임이 어떻게 든 중첩 될 것입니까?

+0

정확히 일치해야합니다. 이러한 경우에 대해 의심이 될 때마다 해체를 확인하는 것이 좋습니다. – Andy

답변

0

스택을 겹칠 수 없습니다.

인수가 전역, 힙 오브젝트이거나 스택에 저장된 경우에도 마지막 요소가 아닐 수 있다고 생각하십시오. 호출 규칙에 따라 다른 요소가 하나의 스택 프레임과 함수에 전달 된 매개 변수 (즉, 반송 주소) 사이에 배치 될 수 있습니다 ...

스택에 아무 ​​것도 추가되지 않아도 결정을 내릴 수 없습니다 함수를 컴파일하는 동안 컴파일러가 호출 함수를 처리 할 때 만들어집니다. 함수가 컴파일되면 호출 된 위치에 따라 함수가 변경되지 않습니다.

+0

링커 인라이닝에 대한 언급이이 질문에 도움이되지 않을 수도 있다고 생각합니다. –

4

이상한 컴파일러를 사용하지 않는 한이 두 호출은 정확히 동일한 코드를 생성해야합니다.

2

다릅니다.

라이브러리로 컴파일 된 경우 대부분의 플랫폼에서 동일하지 않은 경우 두 가지 모두에 대해 생성 된 코드가 동일하게됩니다.

좋은 컴파일러는 그러한 작은 함수를 인라인 할 것이므로, 포인터가 가리키는 값을 증가시키는 스택의 주소를 얻는 대신 값을 직접 증가시킵니다. 인라인 된 함수의 스택 프레임은 호출자의 스택 프레임에 포함되어 있으므로이 경우 오버랩됩니다. 스택 프레임들의 중첩에 관한

+0

그래서 포인터를 취하는 버전은 인라인 될 것이고 대신 포인터로 작업하는 대신 실제 변수에서 직접 작동 할 것입니다. – Mat

+0

@Mat : 참조 버전도 인라인 될 수 있습니다. –

+0

@Mat : 두 변수 모두 인라인되어 실제 변수에서 직접 작업 할 수 있습니다. –

0

I는 다음의 정보 here 발견 일부 목적

, 서브 루틴의 스택 프레임 호출자의는 상기 오버랩 영역 이루어진 중복으로 간주 될 수 어디 매개 변수는 호출자에서 호출 수신자에게 전달됩니다. 일부 환경에서는 호출자가 각 인수를 스택에 푸시하여 스택 프레임을 확장 한 다음 호출 수신자를 호출합니다. 다른 환경에서는 호출자가 호출하는 다른 서브 루틴에 제공하는 인수를 보유하기 위해 스택 프레임의 맨 위에 미리 할당 된 영역이 있습니다. 이 영역은 종종 발신 인수 영역 또는 콜 아웃 영역이라고도합니다. 이 접근법에서 영역의 크기는 호출 된 서브 루틴이 필요로하는 가장 큰 것으로 컴파일러에서 계산됩니다.

따라서 호출자 함수의 로컬 범위에있는 변수 만 foo2에 전달되면 중복 될 수 있습니다!