Явная инициализация мусором
Перенос предложения: голоса +2, -7 Автор идеи: ilnurkh
Возможность не задавать инициализирующий значения является постоянным источником ошибок. Более того, в ряде случаев не возможность явного указания отсутствия начального значения является причиной ненужных действий (например при необходимости создать std::vector с заданным количеством элементов а затем перезаписать все его значения). Предлагаю для начала разрешить код вида: int var = std::uninitialized(); . А также дать возможность писать подобное std::vector vector_with_trash(100, std::unitialized_constructor);
В более радикальной формулировке предлагается запретить создавать переменные и поля без начальных значений. Отказ от явной инициализации должен быть обозначен явным std::uninitialized
Обращаю внимание, что нельзя просто писать std::vector vector_with_trash(100, std::uninitialized
ilnurkh, 5 апреля 2017, 16:00 дублирую описание: Возможность не задавать инициализирующий значения является постоянным источником ошибок. Более того, в ряде случаев не возможность явного указания отсутствия начального значения является причиной ненужных действий (например при необходимости создать std::vector с заданным количеством элементов а затем перезаписать все его значения). Предлагаю для начала разрешить код вида: int var = std::uninitialized(); . А также дать возможность писать подобное std::vector vector_with_trash(100, std::unitialized_constructor);
В более радикальной формулировке предлагается запретить создавать переменные и поля без начальных значений. Отказ от явной инициализации должен быть обозначен явным std::uninitialized
yndx-antoshkka, 7 апреля 2017, 13:18 ilnur.khuziev, int var = std::uninitialized(); не решит проблемы - пользователи будут так писать и будут так же забывать проинициализировать переменные. Проблему пока что лучше всего решают -Wall -Werror которые врубают статический анализ кода и находят места где переменные могут быть не проинициализированы.
Решать проблему с отсутсвием неинициализирующих конструкторов надо сразу для всех контейнеров. У большинства sequence контейнеров есть констуркторы и resize которые принимают только размер, и соответственно будет вызываться std::allocator.construct(pointer) без параметров для инициализации. К сожалению allocator<T>.construct(pointer) вызывает new(pointer) T(); а это проинициализирует T нулём (если T - численный тип). Если подсунуть свой особый аллокатор, то можно избежать инициализации:
template <class T>
struct my_allocator: public std::allocator<T> {
using value_type = typename std::allocator<T>::value_type;
template<class Other>
struct rebind { typedef my_allocator<Other> other; };
template< class U>
void construct(U* p) {
::new (static_cast<void*>(p)) T;
}
};
Только вот контейнер с таким аллокатором нельзя переместить в контейнер с обычным аллокатором.
Просто передать std::uninitialized
Дальше надо исследовать и думать, как решать комплексно решить проблему.
ilnurkh, 7 апреля 2017, 13:28 yndx-antoshkka,
- не решит конечно, но можно делать ворнинг на отстутствие таких указаний (или аттрибутов).
- конечно это не законченное предложение а приглашение к обсуждению
yndx-antoshkka, 10 апреля 2017, 17:00 ilnur.khuziev, есть proposal http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0632r0.html с идеей похожей на идею из пункт 1)
В https://wg21.link/P2723 делают автоматическую инициализацию переменных, в рамках того же предложения хотят добавить механизм для явной инициализации мусором