[MSVC] Инициализация членов класса
От: Abyx Россия  
Дата: 18.04.11 16:06
Оценка:
Сейчас где-то час потратил на то чтобы найти баг в следующем коде:

#include <vector>

struct Foo
{
    Foo() {}

    void load(/*...*/)
    {
        v.clear(); // тут возникает assert "итераторы несовместимы"
    }

    std::vector<int> v;
};

struct Bar
{
    Bar(Foo& f)
    {
        //...
        f.load(/*...*/);
    }
};

struct Holder
{
    Holder()
        : bar(foo)
        , foo()
    {}

    Bar bar;
    Foo foo;
};

int main()
{
    Holder h;
}


Как такого избежать?
In Zen We Trust
Re: [MSVC] Инициализация членов класса
От: Abyx Россия  
Дата: 18.04.11 16:12
Оценка:
Здравствуйте, Abyx, Вы писали:

A>Как такого избежать?


/Wall /analyse не помогает
In Zen We Trust
Re: [MSVC] Инициализация членов класса
От: IROV..  
Дата: 18.04.11 16:13
Оценка:
Здравствуйте, Abyx, Вы писали:

A>Как такого избежать?


MSVC 8 SP1 варнинги не пишет, и не ругаеться.

Если у тебя пишет варнинги, то совет /WX
я не волшебник, я только учусь!
Re: [MSVC] Инициализация членов класса
От: wander  
Дата: 18.04.11 16:15
Оценка:
Здравствуйте, Abyx, Вы писали:

A>Сейчас где-то час потратил на то чтобы найти баг в следующем коде:


struct Holder
{
    Holder()
        : foo() 
          bar(foo)
    {}

    Foo foo;
    Bar bar;
};


A>Как такого избежать?


Местами поменяй инициализацию. Работаешь же с неинициализированной памятью.
Re[2]: [MSVC] Инициализация членов класса
От: IROV..  
Дата: 18.04.11 16:22
Оценка:
Здравствуйте, wander, Вы писали:

W>Местами поменяй инициализацию. Работаешь же с неинициализированной памятью.

Чтото мне подсказывает что такая работа запрещена стандартом, хотя могу ошибаться
я не волшебник, я только учусь!
Re: [MSVC] Инициализация членов класса
От: IROV..  
Дата: 18.04.11 16:23
Оценка: -1
Здравствуйте, Abyx, Вы писали:

A>Как такого избежать?

Писать

: bar(this->foo)

Тогда получишь варнинг
я не волшебник, я только учусь!
Re[3]: [MSVC] Инициализация членов класса
От: wander  
Дата: 18.04.11 16:30
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>Чтото мне подсказывает что такая работа запрещена стандартом, хотя могу ошибаться

Да что вы говорите :)
Re[2]: [MSVC] Инициализация членов класса
От: Abyx Россия  
Дата: 18.04.11 16:57
Оценка:
Здравствуйте, wander, Вы писали:

W>Местами поменяй инициализацию. Работаешь же с неинициализированной памятью.


Это понятно. Мне интересно какие меры надо принять чтобы не повторить такую ошибку в будущем.
In Zen We Trust
Re[2]: [MSVC] Инициализация членов класса
От: Abyx Россия  
Дата: 18.04.11 17:01
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>Писать


IRO>: bar(this->foo)


IRO>Тогда получишь варнинг


очевидно это не тот варнинг

еще можно написать "bar(!@#$%^)" и получить error
In Zen We Trust
Re[3]: [MSVC] Инициализация членов класса
От: wander  
Дата: 18.04.11 17:05
Оценка:
Здравствуйте, Abyx, Вы писали:

A>Это понятно. Мне интересно какие меры надо принять чтобы не повторить такую ошибку в будущем.


Ну что тут сказать. GCC это тоже не диагностирует. Поэтому остается только работать над собой, вырабатывать дисциплину и всегда проверять что за чем должно инициализироваться. А еще лучше отказаться по возможности от написания подобного кода. Ибо error prone.
Re: [MSVC] Инициализация членов класса
От: qqqqq  
Дата: 18.04.11 17:10
Оценка:
gcc выдаст warning в этом случае. Кроме того, статические анализаторы кода должны такие и другие подобные ошибки ловить.
Re[4]: [MSVC] Инициализация членов класса
От: IROV..  
Дата: 18.04.11 17:14
Оценка:
Здравствуйте, 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).

я не волшебник, я только учусь!
Re[2]: [MSVC] Инициализация членов класса
От: wander  
Дата: 18.04.11 17:15
Оценка:
Здравствуйте, qqqqq, Вы писали:

Q>gcc выдаст warning в этом случае.

У меня 4.5 не выдает.

-Wextra -Wall -ansi -pedantic -Weffc++

Comeau тоже не выдает.
Кроме того, мне кажется правильно, что не выдает. С какой стати-то

Q>Кроме того, статические анализаторы кода должны такие и другие подобные ошибки ловить.

Это да.
Re[5]: [MSVC] Инициализация членов класса
От: wander  
Дата: 18.04.11 17:17
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>3.8/5


Позвольте, UB — это не запрещение. Это всего лишь предупреждение о том, что за последствия никто не ручается. Вот если бы такое не компилировалось, тогда да — запрещение.
Re[2]: [MSVC] Инициализация членов класса
От: Abyx Россия  
Дата: 18.04.11 17:19
Оценка:
Здравствуйте, qqqqq, Вы писали:

Q>gcc выдаст warning в этом случае. Кроме того, статические анализаторы кода должны такие и другие подобные ошибки ловить.


да что вы говорите (с) не я
In Zen We Trust
Re[3]: [MSVC] Инициализация членов класса
От: qqqqq  
Дата: 18.04.11 17:21
Оценка:
W>У меня 4.5 не выдает.
Ну не знаю, у меня все время выдавало, когда я с ним работал. Компилятор правда не для Intel, может в этом дело.
Re: [MSVC] Инициализация членов класса
От: Velheart Беларусь  
Дата: 18.04.11 17:21
Оценка:
Здравствуйте, Abyx, Вы писали:

A>Как такого избежать?


Я всегда сразу же после добавления нового члена в класс, добавляю его в список инициализации в конструкторе, новые члены добавляю или в конец, или в конец логической группы членов, чтобы точно случайно не промахнуться и в списке инициализации все члены шли в порядке объявления, оно конечно примитивно и не ахти как идейно, но наряду с обязательной инициализацией локальных переменных, ассертами, подробными трэйсами и прочими штуками, без которых можно как бы и обойтись, в итоге сохраняет кучу времени =)
Re[6]: [MSVC] Инициализация членов класса
От: IROV..  
Дата: 18.04.11 17:24
Оценка:
Здравствуйте, wander, Вы писали:

W>Позвольте, UB — это не запрещение. Это всего лишь предупреждение о том, что за последствия никто не ручается. Вот если бы такое не компилировалось, тогда да — запрещение.


буквоед?

Для меня UB это запрет, просто трудно уловимый компилятором(поэтому он и не ругаеться).
я не волшебник, я только учусь!
Re[7]: [MSVC] Инициализация членов класса
От: wander  
Дата: 18.04.11 17:36
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>буквоед?

Не виноват я, оно само так

IRO>Для меня UB это запрет, просто трудно уловимый компилятором(поэтому он и не ругаеться).

Если на то пошло, то UB там из-за использования ссылки на невалидную память, а не из-за порядка инициализации. Порядок иницализации тут просто поспособствовал этому хорошо.
Re[8]: [MSVC] Инициализация членов класса
От: IROV..  
Дата: 18.04.11 17:44
Оценка: +1 -1
Здравствуйте, wander, Вы писали:

IRO>>Для меня UB это запрет, просто трудно уловимый компилятором(поэтому он и не ругаеться).

W>Если на то пошло, то UB там из-за использования ссылки на невалидную память, а не из-за порядка инициализации. Порядок иницализации тут просто поспособствовал этому хорошо.
Ну я именно это и хотел сказать, что дело не в порядке, а вообще в том что мы используем(разыменовываем) неготовый указатель.
я не волшебник, я только учусь!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.