LINUX.ORG.RU

История изменений

Исправление fsb4000, (текущая версия) :

https://godbolt.org/z/xoM56jdhr

#include <iostream>

#ifndef _MSVC_LIFETIMEBOUND
#if !defined(__has_cpp_attribute)
#define _MSVC_LIFETIMEBOUND
#elif __has_cpp_attribute(msvc::lifetimebound)
#define _MSVC_LIFETIMEBOUND [[msvc::lifetimebound]]
#elif __has_cpp_attribute(_Clang::__lifetimebound__)
#define _MSVC_LIFETIMEBOUND [[_Clang::__lifetimebound__]]
#else
#define _MSVC_LIFETIMEBOUND
#endif
#endif

struct Foo {
    int a_;

    explicit Foo(int a) : a_(a) { std::cout << "C Foo\n"; }
    ~Foo() {
        std::cout << "~ Foo\n";
        a_ = 0;
    }
};

struct Data {
    const Foo &ref_;

    explicit Data(const Foo &_r _MSVC_LIFETIMEBOUND) : ref_(_r) {}

    void print();
};

void Data::print() { std::cout << "Print: " << ref_.a_ << "\n"; }

int main() {
    Data t(Foo(42));

    // Тут ты умер - попытка напечатать 42
    // по ссылке на него, тогда как 42 давно
    // не существует (оно существовало только
    // во время вызова конструктора Data())
    t.print();

    return 0;
}

<source>:36:12: error: temporary whose address is used as value of local variable 't' will be destroyed at the end of the full-expression [-Werror,-Wdangling]
   36 |     Data t(Foo(42));
      |            ^~~~~~~
1 error generated.

Исходная версия fsb4000, :

https://godbolt.org/z/9rheojhfo

#include <iostream>

#ifndef _MSVC_LIFETIMEBOUND
#if !defined(__has_cpp_attribute)
#define _MSVC_LIFETIMEBOUND
#elif __has_cpp_attribute(lifetimebound)
#define _MSVC_LIFETIMEBOUND [[msvc::lifetimebound]]
#elif __has_cpp_attribute(_Clang::__lifetimebound__)
#define _MSVC_LIFETIMEBOUND [[_Clang::__lifetimebound__]]
#else
#define _MSVC_LIFETIMEBOUND
#endif
#endif

struct Foo {
    int a_;

    explicit Foo(int a) : a_(a) { std::cout << "C Foo\n"; }
    ~Foo() {
        std::cout << "~ Foo\n";
        a_ = 0;
    }
};

struct Data {
    const Foo &ref_;

    explicit Data(const Foo &_r _MSVC_LIFETIMEBOUND) : ref_(_r) {}

    void print();
};

void Data::print() { std::cout << "Print: " << ref_.a_ << "\n"; }

int main() {
    Data t(Foo(42));

    // Тут ты умер - попытка напечатать 42
    // по ссылке на него, тогда как 42 давно
    // не существует (оно существовало только
    // во время вызова конструктора Data())
    t.print();

    return 0;
}

<source>:36:12: error: temporary whose address is used as value of local variable 't' will be destroyed at the end of the full-expression [-Werror,-Wdangling]
   36 |     Data t(Foo(42));
      |            ^~~~~~~
1 error generated.