при попытке вывода в неоткрытый поток первого значения у потока выставится флаг badbit;
дальнейшие попытки что-то делать с потоком будут проигнорированы;
программа завершится нормально.
Наблюдаемое поведение (Visual C++ 2008):
флаг выставляется;
после операции вывода в std::ostream_iterator<…>::operator= стоит валидация, которая проверяет, всё ли в порядке с потоком, и, обнаружив badbit, валит меня в _invalid_parameter_noinfo(), которая завершает программу противоестественным способом.
Спрашивается: вроде бы я неопределённого поведения не вызывал; так какого…?
(Аналогичные грабли при попытке взять &v[0] при пустом std::vector<T> v. Неопределённого поведения нет, но Microsoft, собака, бдит.)
Здравствуйте, Centaur, Вы писали:
C>(Аналогичные грабли при попытке взять &v[0] при пустом std::vector<T> v. Неопределённого поведения нет, но Microsoft, собака, бдит.)
как раз есть, нельзя вызывать begin() у пустого контейнера, например тут может падать.
Здравствуйте, Sni4ok, Вы писали:
C>>(Аналогичные грабли при попытке взять &v[0] при пустом std::vector<T> v. Неопределённого поведения нет, но Microsoft, собака, бдит.)
S>как раз есть, нельзя вызывать begin() у пустого контейнера, например тут может падать.
То есть как это foreach(v.begin(), v.end(), f) нельзя? Где написано?
И foreach(&v[0], &v[v.size()], f) тоже должно быть можно, по правилу о том, что можно брать указатель/итератор за последним элементом, постольку, поскольку мы не пытаемся его разыменовывать.
Но вот нет, блин, валидация делается сразу при взятии элемента по индексу.
Здравствуйте, Centaur, Вы писали:
C>>>(Аналогичные грабли при попытке взять &v[0] при пустом std::vector<T> v. Неопределённого поведения нет, но Microsoft, собака, бдит.) S>>как раз есть, нельзя вызывать begin() у пустого контейнера, например тут может падать. C>То есть как это foreach(v.begin(), v.end(), f) нельзя? Где написано? C>И foreach(&v[0], &v[v.size()], f) тоже должно быть можно, по правилу о том, что можно брать указатель/итератор за последним элементом, постольку, поскольку мы не пытаемся его разыменовывать. C>Но вот нет, блин, валидация делается сразу при взятии элемента по индексу.
Вам это сильно мешает?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, Sni4ok, Вы писали:
S>Здравствуйте, Centaur, Вы писали:
C>>(Аналогичные грабли при попытке взять &v[0] при пустом std::vector<T> v. Неопределённого поведения нет, но Microsoft, собака, бдит.)
S>как раз есть, нельзя вызывать begin() у пустого контейнера, например тут может падать.
конечно я тут неправ, я хотел сказать нельзя разиминовывать нулевой элемент, если его не существует
Здравствуйте, Centaur, Вы писали:
C>Здравствуйте, Sni4ok, Вы писали:
C>То есть как это foreach(v.begin(), v.end(), f) нельзя? Где написано?
так можно
C>И foreach(&v[0], &v[v.size()], f) тоже должно быть можно, по правилу о том, что можно брать указатель/итератор за последним элементом, постольку, поскольку мы не пытаемся его разыменовывать.
так нельзя- &v[0] это есть разименование.
C>Но вот нет, блин, валидация делается сразу при взятии элемента по индексу.
любой дебажный stl вам сообщит об ошибке- нетолько студия, но и stlport к примеру.