Здравствуйте, wander, Вы писали:
W>Местами поменяй инициализацию. Работаешь же с неинициализированной памятью.
Чтото мне подсказывает что такая работа запрещена стандартом, хотя могу ошибаться
Здравствуйте, Abyx, Вы писали:
A>Это понятно. Мне интересно какие меры надо принять чтобы не повторить такую ошибку в будущем.
Ну что тут сказать. GCC это тоже не диагностирует. Поэтому остается только работать над собой, вырабатывать дисциплину и всегда проверять что за чем должно инициализироваться. А еще лучше отказаться по возможности от написания подобного кода. Ибо error prone.
Здравствуйте, wander, Вы писали:
W>Здравствуйте, IROV.., Вы писали:
IRO>>Чтото мне подсказывает что такая работа запрещена стандартом, хотя могу ошибаться W>Да что вы говорите :)
3.8/5
Before the lifetime of an object has started but after the storage which the object will occupy has been allocated34)
or, after the lifetime of an object has ended and before the storage which the object occupied is
reused or released, any pointer that refers to the storage location where the object will be or was located
may be used but only in limited ways. Such a pointer refers to allocated storage (3.7.3.2), and using the
pointer as if the pointer were of type void*, is welldefined.
Such a pointer may be dereferenced but the
resulting lvalue may only be used in limited ways, as described below. If the object will be or was of a
class type with a nontrivial
destructor, and the pointer is used as the operand of a deleteexpression,
the
program has undefined behavior. If the object will be or was of a nonPOD
class type, the program has
undefined behavior if:
— the pointer is used to access a nonstatic data member or call a nonstatic member function of the object, or
— the pointer is implicitly converted (4.10) to a pointer to a base class type, or
— the pointer is used as the operand of a static_cast (5.2.9) (except when the conversion is to
void*, or to void* and subsequently to char*, or unsigned char*).
— the pointer is used as the operand of a dynamic_cast (5.2.7).
Здравствуйте, qqqqq, Вы писали:
Q>gcc выдаст warning в этом случае.
У меня 4.5 не выдает.
-Wextra -Wall -ansi -pedantic -Weffc++
Comeau тоже не выдает.
Кроме того, мне кажется правильно, что не выдает. С какой стати-то
Q>Кроме того, статические анализаторы кода должны такие и другие подобные ошибки ловить.
Это да.
Позвольте, UB — это не запрещение. Это всего лишь предупреждение о том, что за последствия никто не ручается. Вот если бы такое не компилировалось, тогда да — запрещение.
Здравствуйте, qqqqq, Вы писали:
Q>gcc выдаст warning в этом случае. Кроме того, статические анализаторы кода должны такие и другие подобные ошибки ловить.
Здравствуйте, Abyx, Вы писали:
A>Как такого избежать?
Я всегда сразу же после добавления нового члена в класс, добавляю его в список инициализации в конструкторе, новые члены добавляю или в конец, или в конец логической группы членов, чтобы точно случайно не промахнуться и в списке инициализации все члены шли в порядке объявления, оно конечно примитивно и не ахти как идейно, но наряду с обязательной инициализацией локальных переменных, ассертами, подробными трэйсами и прочими штуками, без которых можно как бы и обойтись, в итоге сохраняет кучу времени =)
Здравствуйте, wander, Вы писали:
W>Позвольте, UB — это не запрещение. Это всего лишь предупреждение о том, что за последствия никто не ручается. Вот если бы такое не компилировалось, тогда да — запрещение.
буквоед?
Для меня UB это запрет, просто трудно уловимый компилятором(поэтому он и не ругаеться).
Здравствуйте, IROV.., Вы писали:
IRO>буквоед?
Не виноват я, оно само так
IRO>Для меня UB это запрет, просто трудно уловимый компилятором(поэтому он и не ругаеться).
Если на то пошло, то UB там из-за использования ссылки на невалидную память, а не из-за порядка инициализации. Порядок иницализации тут просто поспособствовал этому хорошо.
Здравствуйте, wander, Вы писали:
IRO>>Для меня UB это запрет, просто трудно уловимый компилятором(поэтому он и не ругаеться). W>Если на то пошло, то UB там из-за использования ссылки на невалидную память, а не из-за порядка инициализации. Порядок иницализации тут просто поспособствовал этому хорошо.
Ну я именно это и хотел сказать, что дело не в порядке, а вообще в том что мы используем(разыменовываем) неготовый указатель.