문제

그것은 나에게 보인다는 것을 완벽하게 작동 할 꼬리-재귀 최적화 모두에서는 C 및 C++,아직 디버깅하는 동안 나는 결코 보이시 프레임 스택을 나타내는 이러한 최적화.는 종류의 좋기 때문에 스택는 방법을 알려줍니다 깊은 재귀입니다.그러나,최적화의 좋은뿐만 아니라.

어떤 C++컴파일러에 이렇게 최적화?왜?왜?

어떻게 이동에 대한 컴파일러 그것을 할 수 있나요?

  • 에 대한 MSVC: /O2/Ox
  • 을 위한 GCC: -O2-O3

는 방법에 대해 확인하는 경우 컴파일러는 이 특정한 경우?

  • 에 대한 MSVC,사용 PDB 출력을 추적할 수 있는 코드는,다음의 코드를 검사
  • 을 위한 GCC..?

나는 여전히 취하는 방법에 대한 제안을 결정하는 경우 특정 기능이 최적화되어 있습니다 다음과 같이 컴파일러(더라도 나는 그것을 찾을 안심 콘라드는 나에게 말한다고 가정하 it)

그것은 항상 가능하는지 확인하려면 컴파일러는 이에 만들어 있는 무한 재귀하고 확인하면 그것은 결과에서는 무한 루프 또는 스 오버플로우(이했으로 방문하는 것을 발견 -O2 충분하다),그러나 내가 원하는 것을 확인 할 수 있는 일정 기능을 내가 알고 있는 것입니다 어쨌든 종료.내가 사랑하는 쉬운 방법을 확인하이:)


후에는 어떤 테스트가 소멸자를 파괴의 가능성이 최적화입니다.그것은 때로는 가치가 그것을 변경하는 범위의 특정 변수와 임시 개체 확인하는 범위를 벗어 돌아오기 전에 문을 시작합니다.

어떤 경우 소멸자 요구를 실행할 수 있는 꼬리-전화,꼬리 호출을 최적화 할 수 없습니다.

도움이 되었습니까?

해결책

현재의 모든 컴파일러가 주류 수리 호출 최적화 매우(위해 하고 십년간 보다는 더 많은 것), 도에 대한 상호 재귀화 와 같은:

int bar(int, int);

int foo(int n, int acc) {
    return (n == 0) ? acc : bar(n - 1, acc + 2);
}

int bar(int n, int acc) {
    return (n == 0) ? acc : foo(n - 1, acc + 1);
}

시키는 컴파일러가지 최적화는 간단하다:치에 최적화에 대한 속도:

  • 에 대한 MSVC,사용 /O2/Ox.
  • 을 위한 GCC,그 소리와 ICC,사용 -O3

는 쉬운 방법을 확인하는 경우 컴파일러는 않았다 최적화를 수행하는 것 그렇지 않으면 결과는 스택에서 오버플로우—또는 보 어셈블리에서 출력됩니다.

흥미로운 역사적인 참고,꼬리를 호출 최적화를 위한 C 추가되었 GCC 의 과정에서 학위 논문 에 의해 표시 Probst.논문 설명합니다 몇 가지 흥미로운 주의 사항에 구현합니다.그것은 읽을 가치가있다.

다른 팁

gcc4.3.2 완전히 inlines 이 기능(엉터리/소 atoi() 구현)로 main().최적화 수준 -O1.내가 통지하는 경우 나는 그것을 가지고 놀이(심지어에서 변경 static 하기 extern, 로,꼬리 재귀가리 매우 빠르다,그래서 난 그것에 의존한 프로그램 정확성이 있어야 한다.

#include <stdio.h>
static int atoi(const char *str, int n)
{
    if (str == 0 || *str == 0)
        return n;
    return atoi(str+1, n*10 + *str-'0');
}
int main(int argc, char **argv)
{
    for (int i = 1; i != argc; ++i)
        printf("%s -> %d\n", argv[i], atoi(argv[i], 0));
    return 0;
}

뿐만 아니라 확실한(컴파일러에 이것을 하지 않는 일종의 최적화하지 않는 한 당신이 그것을 물어),거기에 복잡도에 대한 꼬리 전화를 최적화하는 C++에서:소멸자입니다.

주어진 다음과 같습니다.

   int fn(int j, int i)
   {
      if (i <= 0) return j;
      Funky cls(j,i);
      return fn(j, i-1);
   }

컴파일러 수 없습니다(일반적으로)꼬리 호출을 최적화이기 때문에 그것을 필요 전화를 소멸자의 cls 후에 재귀를 호출합니다.

때로는 컴파일러가는 것을 볼 수 있는 소멸자가 없이 외부에 표시되는 부작용(할 수 있도록 수),하지만 그것은 종종 할 수 없습니다.

특히 일반적인 형태의는 곳이 Funky 실제로 std::vector 또는 이와 유사한.

대부분의 컴파일러를 하지 않는 모든 종류의 최적화를 디버그 빌드에서.

를 사용하는 경우 내려 놓으로 구축 PDB 정보 설정에는 이것은 당신이 추적을 통해 최적화된 응용 프로그램과 당신 희망 무엇을 원하다.그러나,디버깅 및 추적 최적의 구축이 뛰어 당신은 주위에,그리고 종종할 수 없는 변수를 조사하으로 직접 그들만이 이제까지 끝에 등록 또는 최적화되어다니다.그것은 새로운 경험을...

으로 그 언급,컴파일러에서는 하지 않을 디버깅 모드입니다.그 확인을 위한 디버그 빌드하는 것보다 느리게 자극을 구축,그러나 그들은 말 충돌 더 자주:경우에 따라 달라집 꼬리를 호출 최적화,그들이 할 수 있습니다.이 때문에 그것은 종종 베를 다시 작성하는 꼬리는 전화로 정상적인 반복입니다.:-(

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