Получить инициализированный по умолчанию (НЕ значение / инициализированный нулем) POD в качестве значения

#include <iostream>

struct A {
    int x;
};

void foo(A a) {
    std::cout << a.x << std::endl;
}

int main() {
    A a;
    foo(a);  // -7159156; a was default-initialized
    foo(A());  // 0; a was value-initialized
}

Можно ли передать значение типа A в foo() без инициализации значения? Нужно ли использовать инициализацию значения или lvalue?

Вы можете спросить, какой смысл избегать инициализации значения, когда она "стоит" не более десяти наносекунд. Как насчет такой ситуации: мы ищем ошибку в унаследованном приложении, вызванную неинициализированным доступом к памяти с помощью valgrind, и ноль НЕ считается допустимым значением для приложения. Инициализация значения не позволит valgrind определить местоположение неинициализированного доступа к памяти.

Вы можете сказать, что печать неинициализированного значения - это UB, но мой "реальный" вариант использования не ограничен печатью. Мой вопрос должен остаться в силе без него.

1 ответ

Если я правильно понимаю вопрос, вам нужна замена для foo(A()); или аналогичные случаи, когда A() называется так, что у вас нет инициализации по умолчанию членов.

В этом случае вот что я придумал:

  • Сначала я попытался добавить A() = default (но это может не работать со старыми стандартами C++), и у меня были интересные результаты. Точный образец, который вы предоставили, работает в обратном порядке: сначала 0, а затем случайное число.

  • Во-вторых, я не использовал A() = default; и просто использовал шаблонную функцию

    template <class T> T make() { T tmp; return tmp; }
    

    За счет копии (или перемещения) вы можете использовать ее как foo(make<A>()) и получите результат, который вы хотели.

Другие вопросы по тегам