C ++ 17 Разве компиляторы не должны определять переход по ссылке на неопределенные значения? - PullRequest
0 голосов
/ 19 сентября 2018

При создании небольшого парсера для проекта я продолжал получать ошибки сегментации ... отследил его до опечатки транспонирования.

Этот пример кода НЕ является исходным кодом, но воспроизводит ошибку.

Я был удивлен, что ни один из моих компиляторов не заметил, что ссылка не инициализирована.

Похоже, что и GCC, и Clang компилируют ее без предупреждения или ошибки.

Разве они не должны отмечать ССЫЛКА НА v2 как неинициализированный?

Я относительно новичок в C ++ и изучаю C ++ 17/20.Но мне любопытно, почему в этом случае компиляторы не обнаруживают, что v2 не определена, а в любом случае передают ссылку на неопределенный объект.

#include <iostream>
#include <vector>
struct A
{
    using vectorA = std::vector<A>;
    int     foo;
    vectorA vA;

    A() = delete; // Implicit but let's be certain!

    A(int f) noexcept
        : foo {f},
          vA  {}
    {}
};

A::vectorA& recurse(A::vectorA& head, int tail) noexcept
{head.emplace_back(tail); return head;}

int main()
{
    // A tree of A's
    A::vectorA v1 {};

    // Fill it using recursive fn converting bars into foos,
    // a bar at a time
    int bar {666};
    A::vectorA v2 {recurse(v2, bar)};
    //                      ^
    // typo of 'v2' instead of 'v1' still compiles!
    // SHOULD, of course, read; A::vector_of_A v2 {recurse(v1, bar)};
    //
    // But v2 is... what exactly? At the point it is passed to recurse?
    // It is uninitialized although it has an address and (likely) space       
    // allocated to hold it.
    // No warning?

    std::cout << "Should this compile?\n";
    std::cout << "Oops! Segmentation Fault Guaranteed!\n";
}

1 Ответ

0 голосов
/ 19 сентября 2018

Если это не скомпилируется, то вы также не сможете сделать следующее, что не является чем-то необычным:

struct base {
    int& x;
    base(int& x) : x(x) {}
};

struct foo : base {
    int x;
    foo() : base(x) {}
};

В то время, когда вызывается конструктор base, x еще не инициализированТем не менее, вполне допустимо хранить ссылку на него для последующего использования.

Это всего лишь один пример, когда получение ссылки на еще не инициализированный объект просто прекрасно, и для запрета на это потребуется написать оченьнепонятный громоздкий код.

...