Почему поток все еще работает с удаленной переменной? - PullRequest
0 голосов
/ 09 апреля 2020

Я ожидаю, что cra sh запрограммирует этот код:

void f(int& ref)
{
    for (auto i{0}; i < 0xfffff; ++i)
    {
        std::clog << i << ":" << ref++ << std::endl;
    }
}

void run(void)
{
    int n = 10;
    std::thread(f, std::ref(n)).detach();
}

int main(void)
{
    run();
    std::this_thread::sleep_for(3s);
}

У меня есть G CC 9.3 и скомпилируйте вышеуказанную программу с параметрами по умолчанию. Когда я запускаю программу, я ожидаю, что cra sh, в функции void f(int&); у нас больше не будет локальной переменной int n;, замедленной в функции void run(void);, но она явно запускает программу и увеличивает переменную ref каждый раз и печатает пока 3 секунды сна в основной функции не закончились. Где я не так делаю?

1 Ответ

2 голосов
/ 09 апреля 2020

Ваш код имеет неопределенное поведение , потому что вы используете ссылку для доступа к объекту, срок жизни которого уже закончился. Существуют некоторые специальные правила, касающиеся продления срока службы при привязке к ссылке const, но они здесь не применяются.

Стандарт C ++ никогда не гарантирует, что ваша программа обработает sh, если вы допустите ошибку. Стандарт C ++ определяет только то, что вы получаете, когда вы компилируете и запускаете правильный код. Не было бы никакой выгоды от указания таких вещей, как «Если вы разыменуете нулевой указатель, вы получите ошибку сегментации». Вместо этого стандарт определяет, что является допустимым кодом, и в основном хранит молчание о том, что происходит, когда вы пишете неверный код C ++. Короче говоря, это то, что такое неопределенное поведение.

Повторение моего комментария:

Если вы пересекаете полосу, когда красные огни, вы не обязательно попадете под машину. Это просто означает, что вы не должны переходить улицу, когда есть красные огни (и когда вы это делаете, вас может сбить машина).

Как и любая аналогия, она не идеальна. Даже если вы не видите приближающуюся машину и знаете, что вас не бьют, вам не следует «переходить улицу», когда «красные огни». Это потому, что код, который опирается на неопределенное поведение, подобное вашему, может сегодня работать, но завтра с другим компилятором, другой версией того же компилятора или даже с тем же компилятором, предназначенным для другой платформы, могут произойти плохие вещи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...