Nekrolm / ubbook

Путеводитель C++ программиста по неопределенному поведению
1.02k stars 48 forks source link

UB: auto and proxy classes #81

Closed sgshulman closed 2 years ago

sgshulman commented 2 years ago

Могу написать небольшую заметку про неожиданное поведение, когда auto комбинируется с контейнерами/операциями, возвращающими прокси объекты. Например, вот такой код

#include <vector>
#include <iostream>

int main()
{
    std::vector<bool> v;
    v.push_back(false);

    std::cout << v[0] << std::endl;

    auto b = v[0];
    b = true;

    std::cout << v[0] << std::endl;

    return 0;
}

выводит

0
1

а с любым целочисленным типом - 0 0.

Что ещё интереснее, неожиданное поведение превращается в неопределённое, причём не единственным способом. Например, можно как получить реаллокацию вектора с висячим прокси объектом, так и явно вызвать оператор [] у временного вектора, т.е. по сути любые способы получения висячих ссылок на элементы вектора годятся, только у нас тут нет ссылок в явном виде. Потому что в обычной ситуации auto получит тип без ссылки (которая есть у возвращаемого значения оператора []) и скопирует значение, но тут у нас не ссылка, а класс, ведущий себя как ссылка.

Кроме того прокси классы используются в Eigen, и можно писать их самому.

Nekrolm commented 2 years ago

Проблема на самом деле более глубокая и статья для нее нужна побольше. То есть написать её, конечно, можно, я не против, но она будет потом подгоняться под общий массив и дополняться