>
struct Base {
    Base() {
        std::cout << "Inside:  " << __PRETTY_FUNCTION__ << std::endl;
    }
    ~Base() {
        std::cout << "Inside:  " << __PRETTY_FUNCTION__ << std::endl;
    }
};
struct BaseWrapper {
    const Base &b;
};
int main()
{
    {
        auto *w = new BaseWrapper{{}};
        std::cout << "Inside:  " << __PRETTY_FUNCTION__ << std::endl;
        delete w;
    }
    return 0;
}

위 코드는 C ++ 11 또는 C ++ 14로 컴파일 할 때 예상 한대로 작동하지만 C ++ 17로 컴파일 할 때 다음과 같은 내용을 제공합니다.

Inside:  Base::Base()                                                                                                                                                              
Inside:  int main()

보시다시피 Base :: ~ Base ()는 호출되지 않았습니다. 나에게는별로 이해가되지 않습니다. 이 코드는 Ubuntu 18.04.1 LTS의 GCC 7.3.0 및 OnlineGDB 에서이 코드를 테스트했습니다. 모두 같은 결과를냅니다.

이것이 C ++ 17의 새로운 기능인지 아니면 버그인지 궁금합니다.

업데이트 : 나는 w->b 를 잘 알고 있습니다  매달려있는 참조입니다. 실제로, 나는 그것을 보여주기 위해 의도적 으로이 코드를 썼습니다. 그런 다음 테스트하는 동안이 문제를 발견했습니다.

내가 정말로 알고 싶은 것은 GCC 7.3을 고수해야하는 경우이 문제가 얼마나 심각합니까? 또는 같은 문제를 재현하는 다른 방법이 있다면? 또는 결함 보고서?


  • 답변 # 1

    명백히, 표준은 동작이 정의되지 않았다고 말하지 않는 한, 작성되었지만 파괴되지 않은 임시는 컴파일러 버그입니다. 그러나 예제는 잘 정의되어 있습니다. 표준 [class.temporary]의 관련 규칙 :

    와이즈 비즈

  • 답변 # 2

    참조 수명 연장 및 힙 할당 객체가있는 버그처럼 보입니다.

    레퍼런스 멤버의 집계 초기화에 이상한 수명 연장 규칙이 있습니다.

    컴파일러를 업그레이드하거나 간단히

    When an implementation introduces a temporary object of a class that has a non-trivial constructor ([class.default.ctor], [class.copy.ctor]), it shall ensure that a constructor is called for the temporary object. Similarly, thedestructor shall be called for a temporary with a non-trivial destructor([class.dtor]). Temporary objects are destroyed as the last step in evaluating the full-expression ([intro.execution]) that (lexically) contains the point where they were created. ...

    There are three contexts in which temporaries are destroyed at a different point than the end of the full-expression. ...

    The third context is when a reference is bound to a temporary object ...

    The exceptions to this lifetime rule are:

      ...

      Atemporarybound to a reference in a new-initializer ([expr.new])persists until the completion of the full-expression containing the new-initializer.

    를 추가 할 수 있습니다  ctor와 버그가 증발하는 것을 지켜보십시오.

    BaseWrapper(Base const& bin):b(bin){}

  • 이전 version - 워크 벤치에서 mysql vesion을 업그레이드하려면
  • 다음 sap - A80은 SE80에서 잘 작동하지만 Z tcode에서는 잘 작동하지 않습니다