문제

어제,나 자신을 발견 코드를 작성하는 다음과 같다:

SomeStruct getSomeStruct()
{
    SomeStruct input;

    cin >> input.x;
    cin >> input.y;
}

물론을 잊을 실제로 반환하는 구조체가 그냥 만들어집니다.이상하게도,이 값을 구하는 이 함수를 통해 반환되는 초기화되어 제로(사용하여 컴파일하면은 g++는).이것은 그냥 우연 또는 다른 SomeStruct 을 얻을 만들고 초기화 암시적으로 어딘가에?

도움이 되었습니까?

해결책

다른 소화 구조가 어딘가에서 암시 적으로 생성되고 초기화 되었습니까?

구조물이 어떻게 반환되는지 생각해보십시오. 둘 다 x 그리고 y 비트 32 비트, 32 비트 아키텍처의 레지스터에 맞지 않기에는 너무 큽니다. 64 비트 아키텍처에서 64 비트 값에 동일하게 적용됩니다 (@Denton Gentry의 답변은 더 간단한 값이 어떻게 반환되는지 언급 함). 어딘가에 할당되어야합니다. 이를 위해 힙을 사용하는 것이 낭비되므로 스택에 할당되어야합니다. 그러나 그것은 당신의 스택 프레임에있을 수 없습니다. getSomeStruct 함수는 함수가 반환 된 후 더 이상 유효하지 않기 때문에 함수.

컴파일러는 대신 발신자에게 호출 된 함수를 알 수있는 공간에 숨겨진 포인터를 전달함으로써 결과 (호출자의 스택 어딘가에있을 것)를 넣을 위치를 알려줍니다 (아마도 발신자 스택의 어딘가에 있음). 그래서 0으로 설정되는 곳은 방문객, 당신의 것이 아닙니다 getSomeStruct 기능.

추가 사본을 제거 할 수있는 "명명 된 값 반환 최적화"와 같은 최적화도 있습니다. 그래서, 당신은 누락 된 것을 사용 했습니까? return, 결과는 임시를 생성하고 복사하는 대신 발신자가 할당 한 공간에서 직접 생성됩니다.

무슨 일이 일어나고 있는지에 대한 자세한 내용은 발신자 기능을 살펴 봐야합니다. "빈"을 초기화하는 것입니다 (0으로) SomeStruct 나중에 귀하의 반환 값을 할당하는 getSomeStruct 기능? 아니면 다른 일을하고 있습니까?

다른 팁

에서 떨어지는 종료하는 함수의 선언을 반환 값(지 않고 명시적으로 반환값)리드를 정의되지 않은 결과입니다.Gcc 에 대해,당신은 시작과 -Wall 명령 라인 스위치집에 가장 유용한 경고.특정 gcc 경고 통제하는 경고 당신이 원하는 -Wreturn-type (에 포함되는 -Wall, 에,나는 그냥 언급은 이에 대한 완성도).

면 경고 설정에서,당신은 또한 사용 -Werror 경고를 오류로 처리하고 구축에 중점 검색 오류가 있습니다.

대부분의 최신 CPU 아키텍처에 대한 호출 규칙은 기능 리턴 값을 발신자에게 전달하기 위해 특정 레지스터를 지정합니다. 발신자는 함수 호출을 한 다음 지정된 레지스터를 반환 값으로 사용합니다. 값을 명시 적으로 반환하지 않으면 발신자는 해당 레지스터에있는 쓰레기가 무엇이든 사용합니다.

컴파일러는 또한 함수 내부 계산에 사용할 수있는 모든 레지스터를 사용합니다. 리턴 값을 유지하기 위해 지정된 레지스터는 함수 내 MISC 계산에도 사용됩니다. 따라서 반환 값을 지정하는 것을 잊어 버린 경우 올바른 값이 기적적으로 발신자에게 반환되는 것은 드문 일이 아닙니다. 객체를 저장하는 데 등록한 컴파일러가 사용되었습니다.

불행히도 함수에 대한 사소한 변경조차도 레지스터 할당이 변경 될 수 있으므로 반환 값은 실제 쓰레기가됩니다.

나는 이것이 흥미 롭다는 것을 알았다. 기본 옵션을 사용하면 다음 컴파일러는 다음과 같은 동작을합니다. GetSomeStruct() 기능:

  • Microsoft VC, 모든 버전 (어쨌든 VC6 이후) :

    error C4716: 'getSomeStruct' : must return a value

  • 디지털 화성 :

    Warning 18: implied return of getSomeStruct at closing '}' does not return value

  • comeau :

    warning: missing return statement at end of non-void function "getSomeStruct"

  • GCC :

    오류 나 경고가 없습니다

표준 (6.6.3 단락 2)의 다음 몇 문장을 감안할 때 :

표현식이없는 반환 명령문은 값을 반환하지 않는 함수, 즉 리턴 유형 void가있는 함수, 생성자 (12.1) 또는 소멸자 (12.4)에서만 사용할 수 있습니다. ... 함수의 끝에서 흐르는 것은 값이없는 반환과 동일합니다. 이로 인해 가치 회복 함수에서 정의되지 않은 동작이 발생합니다.

이 경우 컴파일러가 오류를주지 않을 이유가 거의 없다고 말하고 싶습니다. 왜 그렇게 많은 컴파일러가 경고 만 제공하거나 진단이 전혀 없습니까?

나에게 컴파일러는 그것을 허용하지 않았다. http://codepad.org/kkzvcesh

당신은 가지고 있지 않았기 때문에 어떤 경고도받지 못했습니다 -Wall -Werror 켜졌다. (다른 답변에 언급 된 바와 같이)

그러나 스택 객체가 발신자 함수에서 기본값, 아마도 명백한 제로 인수 또는 스택의 0으로 인해 기본적으로 구성되어 있었기 때문에 결과적으로 구조적으로 구조물을 얻었을 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top