не получается перегрузить operator==
От: sushko Россия  
Дата: 19.05.15 08:06
Оценка:
Hi, All!

У меня в VisualC 10 есть класс с перегруженным operator==. Когда я в коде пишу сравнение двух экземпляров этого класса, в отладчике я вижу, что в перегруженный operator== выполнение программы просто не заходит, считая результат операции всегда TRUE. Почему?

class CMoney
{
public:
    BOOL operator==(CMoney &other)
    {
        ASSERT(m_iCurrencyID == other.m_iCurrencyID);
        return (m_fAmount == other.m_fAmount);
    }
private:
    double m_fAmount;
    int m_iCurrencyID;
}
Бесплатный генератор отчетов для программ на C/C++
http://www.oxetta.com
Re: не получается перегрузить operator==
От: sushko Россия  
Дата: 19.05.15 08:17
Оценка:
Сейчас закомментировал этот оператор, и проект скомпилировался несмотря на то, что в коде есть его вызовы типа if (money1 == money2). Я явно что-то делаю не то, но вот что...
Бесплатный генератор отчетов для программ на C/C++
http://www.oxetta.com
Re: не получается перегрузить operator==
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 19.05.15 08:32
Оценка: +2
Здравствуйте, sushko, Вы писали:

И хорошо что не заходит. Сравнение даблов через == это как разбрасывание граблей по полю с высокой травой.
Sic luceat lux!
Re[2]: не получается перегрузить operator==
От: uzhas Ниоткуда  
Дата: 19.05.15 08:34
Оценка: +2
Здравствуйте, sushko, Вы писали:

S>Сейчас закомментировал этот оператор, и проект скомпилировался несмотря на то, что в коде есть его вызовы типа if (money1 == money2). Я явно что-то делаю не то, но вот что...

сигнатура метода должна быть такой:
bool operator==(const CMoney& other) const
{
...
}


нужно показать больше кода (минимальный пример) и ошибку компилятора, чтобы мы могли помочь
Re: не получается перегрузить operator==
От: PM  
Дата: 19.05.15 08:38
Оценка:
Здравствуйте, sushko, Вы писали:

S>У меня в VisualC 10 есть класс с перегруженным operator==. Когда я в коде пишу сравнение двух экземпляров этого класса, в отладчике я вижу, что в перегруженный operator== выполнение программы просто не заходит, считая результат операции всегда TRUE. Почему?


Лучше сделать operator== константным, чтобы он работал бы и константными объектами. И добавить оператор != для полноты:

S>
S>class CMoney
S>{
S>public:
S>    bool operator==(CMoney const& other) const
S>    {
S>        ASSERT(m_iCurrencyID == other.m_iCurrencyID);
S>        return (m_fAmount == other.m_fAmount);
S>    }
      bool operator!=(CMoney const& other) const { return !(*this == other); }
S>private:
S>    double m_fAmount;
S>    int m_iCurrencyID;
S>}
S>


Вообще сравнивать на равенство числа в формате с плавающей точностью (float/double) — очень плохая идея, т.к. из-за потери точности результаты математически равных выражений могут оказаться неравными. И название класса как-бы намекает на необходимость точных результатов.

Включив режим телепата, рискну предположить, что CMoney::operator== не вызвается из-за того, что в классе определен оператор преобразвания к какому-то встроенному типу, например CMoney::operator double()
Re: не получается перегрузить operator==
От: VTT http://vtt.to
Дата: 19.05.15 08:45
Оценка:
При отладке можно поставить breakpoint на if (money1 == money2) и воспользоваться командой step into которая покажет, что именно там вызывается, или ассемблер поглядеть.
А проблема скорее всего из-за того, что там в классе объявлен какой-нибудь оператор приведения к встроенному типу, который и вызывается неявно перед сравнением.
Ну и, как выше писали, сравнивать double через == не стоит. Это не математика, вычисления одной величины разными способами дает не совсем одинаковый результат. Поэтому при сравнении стоит ввести некоторую величину погрешности, при который две величины будут считаться (примерно) равными.
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Отредактировано 19.05.2015 8:52 VTT . Предыдущая версия .
Re: не получается перегрузить operator==
От: утпутуук  
Дата: 19.05.15 09:00
Оценка:
Здравствуйте, sushko, Вы писали:

Может нужно добавить:

S>
S>    BOOL operator==(const CMoney &other)
S>


Деньги хранить в даблах? Хм...

И да, сам метод тоже константным стоит сделать
Отредактировано 19.05.2015 9:02 утпутуук . Предыдущая версия .
Re[2]: не получается перегрузить operator==
От: landerhigh Пират  
Дата: 19.05.15 09:03
Оценка:
Здравствуйте, sushko, Вы писали:

S>Сейчас закомментировал этот оператор, и проект скомпилировался несмотря на то, что в коде есть его вызовы типа if (money1 == money2). Я явно что-то делаю не то, но вот что...


дай угадаю. Сравниваешь не объекты, а указатели?

И еще, добавлю к уже сказанному — выкинь ASSERT. Совсем. И больше не трогай.
www.blinnov.com
Re[3]: не получается перегрузить operator==
От: sushko Россия  
Дата: 19.05.15 09:19
Оценка:
S>>Сейчас закомментировал этот оператор, и проект скомпилировался несмотря на то, что в коде есть его вызовы типа if (money1 == money2). Я явно что-то делаю не то, но вот что...
U>сигнатура метода должна быть такой:
U>
U>bool operator==(const CMoney& other) const
U>{
U>...
U>}
U>


Спасибо, помогло!

U>нужно показать больше кода (минимальный пример) и ошибку компилятора, чтобы мы могли помочь


Не было никаких ошибок компилятора, все компилировалось и работало. Правда, работало неправильно
Бесплатный генератор отчетов для программ на C/C++
http://www.oxetta.com
Re[3]: не получается перегрузить operator==
От: sushko Россия  
Дата: 19.05.15 09:21
Оценка:
S>>Сейчас закомментировал этот оператор, и проект скомпилировался несмотря на то, что в коде есть его вызовы типа if (money1 == money2). Я явно что-то делаю не то, но вот что...

L>дай угадаю. Сравниваешь не объекты, а указатели?


Не, объекты сравниваю.

L>И еще, добавлю к уже сказанному — выкинь ASSERT. Совсем. И больше не трогай.


Как говорят братья-уголовники — обоснуй?
Бесплатный генератор отчетов для программ на C/C++
http://www.oxetta.com
Re: не получается перегрузить operator==
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 19.05.15 09:23
Оценка:
Здравствуйте, sushko, Вы писали:

А давайте подумаем как лучше задизанийть класс CMoney? Мне кот кажется CurrencyId должен быть классом Currency, а CMoney шаблонным классом и параметризироваться Currency. Тогда это позволить сделать проверку в compile time сравнения "двух денег" разной Currency.
Sic luceat lux!
Re[2]: не получается перегрузить operator==
От: sushko Россия  
Дата: 19.05.15 09:24
Оценка: :)
PM>Лучше сделать operator== константным, чтобы он работал бы и константными объектами. И добавить оператор != для полноты:

Вы были правы, и именно в этом все и было дело. Оператор== незаоверрайдился из-за того, что он был не-константным и не совпали сигнатуры методов.

PM>Вообще сравнивать на равенство числа в формате с плавающей точностью (float/double) — очень плохая идея, т.к. из-за потери точности результаты математически равных выражений могут оказаться неравными. И название класса как-бы намекает на необходимость точных результатов.


К сожалению, вылечить это — примерно 3 месяца работы: проект большой, и этот класс не единственный, кто (напрасно) работает с double. Когда-нибудь сделаю.

PM>Включив режим телепата, рискну предположить, что CMoney::operator== не вызвается из-за того, что в классе определен оператор преобразвания к какому-то встроенному типу, например CMoney::operator double()


Берегите ваш режим телепата, он, по ходу, работает очень точно. Это был operator LPCTSTR()
Бесплатный генератор отчетов для программ на C/C++
http://www.oxetta.com
Re[2]: не получается перегрузить operator==
От: sushko Россия  
Дата: 19.05.15 09:27
Оценка:
K>А давайте подумаем как лучше задизанийть класс CMoney? Мне кот кажется CurrencyId должен быть классом Currency, а CMoney шаблонным классом и параметризироваться Currency. Тогда это позволить сделать проверку в compile time сравнения "двух денег" разной Currency.

Не, так, к сожалению, сделать не получится. В этом конкретном проекте, я имею в виду.
Бесплатный генератор отчетов для программ на C/C++
http://www.oxetta.com
Re[4]: не получается перегрузить operator==
От: landerhigh Пират  
Дата: 19.05.15 10:01
Оценка: -3
Здравствуйте, sushko, Вы писали:

L>>дай угадаю. Сравниваешь не объекты, а указатели?

S>Не, объекты сравниваю.

Значит, не угадал.

L>>И еще, добавлю к уже сказанному — выкинь ASSERT. Совсем. И больше не трогай.


S>Как говорят братья-уголовники — обоснуй?


Уголовники мне не братья.

Во-первых, бездумное использование ассертов как минимум бессмысленно, а чаще всего просто вредно. Использовать нужно тесты.
А в данном случае вообще вредно — в дебаге ты получишь вылет при сравнении разных валют, а в релизе такие значения молча прожуются. Салют трудноуловимым багам, и вопрос даже не в "если" а в "когда". Рано или поздно в продакшене у тебя кто-то купит нечто, что стоит 20 килоуе за 20 килонеуе.
Если нельзя сравнивать разные валюты, то это должно быть закреплено контрактом в коде, а не отладочной ловушкой. В данном случае можно бросить исключение. Если логика допускает, то этот оператор может тупо возвращать false при попытке сравнения разных валют. С оператором < такой номер уже так просто не пройдет.
www.blinnov.com
Re[5]: не получается перегрузить operator==
От: Кодт Россия  
Дата: 19.05.15 12:07
Оценка: +1
Здравствуйте, landerhigh, Вы писали:

L>Во-первых, бездумное использование ассертов как минимум бессмысленно, а чаще всего просто вредно. Использовать нужно тесты.


Да ладно!
Ассерты нужны как раз на тот случай, чтобы удостовериться в покрытии тестами. А то на всякий чих не наздравствуешься.

Вот намедни поймал такую протечку ошибки: глючный сервер заставил глючить SSL-стек браузера. Теоретически, надо было это диагностировать на ранней стадии, но у авторов не хватило фантазии сделать такие проверки и покрыть такими тестами.
В итоге мусор на входе просочился за гематоэнцефалический барьер и привёл к неопределённому поведению. Которое выразилось в нарушении ассерта, к счастью, не очень далеко от места возникновения ошибки. А не было бы ассерта, полетели бы клочки по закоулочкам.

L>А в данном случае вообще вредно — в дебаге ты получишь вылет при сравнении разных валют, а в релизе такие значения молча прожуются. Салют трудноуловимым багам, и вопрос даже не в "если" а в "когда". Рано или поздно в продакшене у тебя кто-то купит нечто, что стоит 20 килоуе за 20 килонеуе.

L>Если нельзя сравнивать разные валюты, то это должно быть закреплено контрактом в коде, а не отладочной ловушкой. В данном случае можно бросить исключение.

В этом большая польза макросов. Определить ассерт так, чтобы заодно кидал исключение "всё вааащщще плохо!" (и в релизе тоже).
Если клиентский код должен отличаться повышенной живучестью, он это исключение поймает и перезапустит нужную подсистему.

L>Если логика допускает, то этот оператор может тупо возвращать false при попытке сравнения разных валют. С оператором < такой номер уже так просто не пройдет.
Перекуём баги на фичи!
Re[6]: не получается перегрузить operator==
От: landerhigh Пират  
Дата: 19.05.15 12:42
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Да ладно!

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

Эээ, не догнал от слова совсем. Как ассерты помогут удостовериться, что все сценарии покрыты?
Не говоря уже о том, что тесты вообще нужно в релизе гонять

К>Вот намедни поймал такую протечку ошибки: глючный сервер заставил глючить SSL-стек браузера. Теоретически, надо было это диагностировать на ранней стадии, но у авторов не хватило фантазии сделать такие проверки и покрыть такими тестами.

К>В итоге мусор на входе просочился за гематоэнцефалический барьер и привёл к неопределённому поведению. Которое выразилось в нарушении ассерта, к счастью, не очень далеко от места возникновения ошибки. А не было бы ассерта, полетели бы клочки по закоулочкам.

Это называется "повезло". UB оно ж на то и UB, что его B — U. Оно с тем же успехом могло и через ассерт просочиться и до него дров наломать, и вообще левую память снайперски порасстреливать. И опять же, а если оно только в релизе стреляет?

Вот у меня недавно случай был. На юнит-тестах, кстати. В дебаге все пучком, а в релизе случилось нечто. Тест кейс практически вида ASSERT_EQ(3, code_that_does_something_then_adds_two_numbers(2, 1)) падал, код упорно вычислял 2+1 как 2. На деле немножко сложнее, конечно, но суть именно такая. Оказалось, баг в оптимизаторе, да не простой, а во время link-time code generation. Оно посчитало, что результат сложения 2 и 1 никому будет не нужен и аккуратно выкинуло соотвествующий кусочек логики
И что обидно, урезать проект до минимума, на котором воспроизводится, не удалось. Видимо, связано с объемом кода или еще какой чертовщиной. Вот не будь у меня привычки полагаться на проверку наблюдаемого поведения (ака тесты), был бы мне сюрпризец через месяц, когда прототип в тестирование передавали.

L>>А в данном случае вообще вредно — в дебаге ты получишь вылет при сравнении разных валют, а в релизе такие значения молча прожуются. Салют трудноуловимым багам, и вопрос даже не в "если" а в "когда". Рано или поздно в продакшене у тебя кто-то купит нечто, что стоит 20 килоуе за 20 килонеуе.

L>>Если нельзя сравнивать разные валюты, то это должно быть закреплено контрактом в коде, а не отладочной ловушкой. В данном случае можно бросить исключение.

К>В этом большая польза макросов. Определить ассерт так, чтобы заодно кидал исключение "всё вааащщще плохо!" (и в релизе тоже).


Может быть, но тут имхо проблема лежит в другой плоскости. Поскольку деньги имеют свойство "валюта", то правила сравнения таких денег должны оговариваться контрактами, т.е. это должно быть отражено в архитектуре системы.
www.blinnov.com
Re[2]: не получается перегрузить operator==
От: MasterZiv СССР  
Дата: 19.05.15 12:50
Оценка:
Здравствуйте, утпутуук, Вы писали:

S>>
S>>    BOOL operator==(const CMoney &other)
S>>


У>Деньги хранить в даблах? Хм...


Вообще-то допустимо, если это, например, финансовые или статистические расчёты. Там точность не нужна.
Re[7]: не получается перегрузить operator==
От: uzhas Ниоткуда  
Дата: 19.05.15 12:55
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Как ассерты помогут удостовериться, что все сценарии покрыты?


ты слишком категоричен, польза от ассертов в дебаге есть
для повышения качества софта используют кучу средств, в том числе
1) ассерты только в дебаге
2) ассерты в релизе
3) исключения
4) покрытия тестами
и тд

вещи почти ортогональные и друг друга дополняющие
ассерты в дебаге могут помочь выявить неправильное использование класса в новом коде, они как бы декларируют контракт (какими должны быть входные данные и внутренние инварианты). они отключаются в релизе, что может способствовать созданию более оптимального кода
на практике это приводит дилемме: либо надежно, либо быстро

зы. так уж сложилось, что на текущем месте мы не используем debug-only ассерты, наши ассерты не приводят к аборту : есть возможностью выйти из функции по return или throw с записью ошибки в лог. кто-то может сказать, что это и не ассерт, но холиворить я не хочу на эту тему (уже давно пережевывали на этом форуме)
Re[8]: не получается перегрузить operator==
От: landerhigh Пират  
Дата: 19.05.15 13:10
Оценка: :)
Здравствуйте, uzhas, Вы писали:

U>для повышения качества софта используют кучу средств, в том числе

U>1) ассерты только в дебаге

Вот ни разу не видел "повышения качества софта" от таких ассертов. Как правило, просто ставят ловушку на некий сценарий, подумать о корректной обработке которого ниасилили. Потом выплывают сюрпризы в релизе. Может быть, где-то их и используют обдуманно, но я еще не видел

U>2) ассерты в релизе


Ой мама

U>3) исключения


Это ортогонально качеству софта

U>4) покрытия тестами

U>и тд

U>вещи почти ортогональные и друг друга дополняющие

U>ассерты в дебаге могут помочь выявить неправильное использование класса в новом коде, они как бы декларируют контракт (какими должны быть входные данные и внутренние инварианты).

Это больше вопрос проектирования и/или документирования. Коду вида "универсальный всемогутор" обкладывание ассертами помогает плохо, код же, при написании которого старались следовать SOLID, зачастую с нарушением контракта еще и не применишь.

U>они отключаются в релизе, что может способствовать созданию более оптимального кода

U>на практике это приводит дилемме: либо надежно, либо быстро

ага, и к тому, что продакшен идет дебаг-сборка
www.blinnov.com
Re[7]: не получается перегрузить operator==
От: Кодт Россия  
Дата: 19.05.15 15:50
Оценка:
Здравствуйте, landerhigh, Вы писали:

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

L>Эээ, не догнал от слова совсем. Как ассерты помогут удостовериться, что все сценарии покрыты?
L>Не говоря уже о том, что тесты вообще нужно в релизе гонять

А вот так. Сидишь себе в дебажной сборке, отлаживаешь совсем другой предмет... и тут вдруг бабах, пароход перевернулся! Теряешь монокль O_o, вставляешь монокль обратно, и начинаешь увеличивать метрику кода WTF/min.

L>Это называется "повезло". UB оно ж на то и UB, что его B — U. Оно с тем же успехом могло и через ассерт просочиться и до него дров наломать, и вообще левую память снайперски порасстреливать. И опять же, а если оно только в релизе стреляет?


А не было бы ассерта, вообще не повезло бы.

К>>В этом большая польза макросов. Определить ассерт так, чтобы заодно кидал исключение "всё вааащщще плохо!" (и в релизе тоже).


L>Может быть, но тут имхо проблема лежит в другой плоскости. Поскольку деньги имеют свойство "валюта", то правила сравнения таких денег должны оговариваться контрактами, т.е. это должно быть отражено в архитектуре системы.


Но может быть и такой сценарий.
Код верифицирован "мамой клянус, здесь и здесь всегда одинаковая валюта", а кто-то из разработчиков вспомнил золотые слова Рейгана — "доверьяй но проверьяй".
Перекуём баги на фичи!
Re[9]: не получается перегрузить operator==
От: Кодт Россия  
Дата: 19.05.15 16:06
Оценка:
Здравствуйте, landerhigh, Вы писали:

U>>1) ассерты только в дебаге

L>Вот ни разу не видел "повышения качества софта" от таких ассертов. Как правило, просто ставят ловушку на некий сценарий, подумать о корректной обработке которого ниасилили. Потом выплывают сюрпризы в релизе. Может быть, где-то их и используют обдуманно, но я еще не видел

Ну не все же используют TDD.
Сперва фигачится бизнес-логика, а потом, так и быть, ключевые места добавляются в тесты.

U>>2) ассерты в релизе

L>Ой мама

1. Системные тесты.
2. Девиз эрланга — Let them crash.

U>>они отключаются в релизе, что может способствовать созданию более оптимального кода

U>>на практике это приводит дилемме: либо надежно, либо быстро

L>ага, и к тому, что продакшен идет дебаг-сборка


Как насчёт фазы "отладка на стороне заказчика"?
Перекуём баги на фичи!
Re[8]: не получается перегрузить operator==
От: landerhigh Пират  
Дата: 19.05.15 23:27
Оценка:
Здравствуйте, Кодт, Вы писали:

К>А вот так. Сидишь себе в дебажной сборке, отлаживаешь совсем другой предмет... и тут вдруг бабах, пароход перевернулся! Теряешь монокль O_o, вставляешь монокль обратно, и начинаешь увеличивать метрику кода WTF/min.


Ааа... я на полном серьезе уже и не помню, когда приходилось сидеть в дебажной сборке. Особенно при разработке. Вот ковырять релизную сборку (ага, оптимизатор услужил) и глядеть в крешдампы иногда приходится. А так тестами справлялись.
Ну и опять же, чтобы ассерт сработал, нужно, чтобы кто-нибудь подумал "может бабахнуть" и его вставил. А это уже 90% успеха. Обычно все намного грустнее.

L>>Это называется "повезло". UB оно ж на то и UB, что его B — U. Оно с тем же успехом могло и через ассерт просочиться и до него дров наломать, и вообще левую память снайперски порасстреливать. И опять же, а если оно только в релизе стреляет?


К>А не было бы ассерта, вообще не повезло бы.


Это анекдот про блондинку и динозавра какой-то

L>>Может быть, но тут имхо проблема лежит в другой плоскости. Поскольку деньги имеют свойство "валюта", то правила сравнения таких денег должны оговариваться контрактами, т.е. это должно быть отражено в архитектуре системы.


К>Но может быть и такой сценарий.

К>Код верифицирован "мамой клянус, здесь и здесь всегда одинаковая валюта", а кто-то из разработчиков вспомнил золотые слова Рейгана — "доверьяй но проверьяй".

Вообще, имхо есть два случая. Один — когда тип "деньги" — простой numeric. Естественно, никакого свойства "валюта" нет. Это, кстати, логично. Валюта — понятие более высокого уровня и должно относиться к счету. А "деньги" — это просто количество этих фантиков.
Второй — когда тип "деньги" имеет свойство "валюта". В этом случае он обязан определять контракт операций с разными валютами. Без вариантов. Хотя бы явный запрет любых таких операций, или же реализация их через курс. Последнее, кстати, криво, т.к. понятие "курс", необходимое для сравнения двух разных валют — внешнее по отношению к типу "деньги" и зависит от многих факторов. Например, даты операции. Короче, дизайн кривой, как ни крути.
Единственные несколько разумных юзкейсов, о которых я сейчас могу подумать, это реализация защиты от случайного сравнения рублей с рупиями или там идентификация валюты на входе в систему, когда удобно объединить информацию о валюте с суммой.
www.blinnov.com
Re[10]: не получается перегрузить operator==
От: landerhigh Пират  
Дата: 19.05.15 23:38
Оценка: :)
Здравствуйте, Кодт, Вы писали:

К>Ну не все же используют TDD.


Это правда. Жаль, но правда.

К>Сперва фигачится бизнес-логика, а потом, так и быть, ключевые места добавляются в тесты.


И так тоже.

U>>>2) ассерты в релизе

L>>Ой мама

К>1. Системные тесты.


Ну системный тест — это не ассерт в релизе. Это чОрный йащик. Иногда белый, но чаще черный.

L>>ага, и к тому, что продакшен идет дебаг-сборка


К>Как насчёт фазы "отладка на стороне заказчика"?


Кстати, такое тоже бывало, но не по нашей воле. Это вынужденная мера. Кто ж виноват, что каждый производитель оборудования, соответствующего индустриальному стандарту, умудрился понять стандарт по-своему? Правда, я в один момент постиг дзен настолько, что из описания проблемы на чайнглише в пересказе француза на ломаном английском, не глядя ни в код, ни в логи, мог с 99% вероятностю сказать, где именно вендор налошил и что теперь делать, как это можно просимулировать в лаборатории или на симуляторе, не имея доступа к девайсу и как можно организовать воркэраунд.
А вот к классической отладке системы управления электростанциями и прочим производством на своей стороне наши заказчики относились с плохо скрываемой прохладцей. Почему — не знаю. Этих заказчиков не поймешь
www.blinnov.com
Re[4]: не получается перегрузить operator==
От: landerhigh Пират  
Дата: 20.05.15 06:59
Оценка:
Здравствуйте, sushko, Вы писали:

U>>нужно показать больше кода (минимальный пример) и ошибку компилятора, чтобы мы могли помочь


S>Не было никаких ошибок компилятора, все компилировалось и работало. Правда, работало неправильно


Как говорится, компьютер сделает все, что вы ему скажете, но это будет отличаться от того, что вы имели в виду
www.blinnov.com
Re[8]: не получается перегрузить operator==
От: sushko Россия  
Дата: 20.05.15 07:02
Оценка:
Здравствуйте, uzhas, Вы писали:

U>4) покрытия тестами


А что такое "покрытие тестами"? Речь идет о какой-то особенной системе автоматического тестирования со стоимостью в тысячи долларов за рабочее место или о чем-то более простом типа макроса ASSERT()?
Бесплатный генератор отчетов для программ на C/C++
http://www.oxetta.com
Re[9]: не получается перегрузить operator==
От: landerhigh Пират  
Дата: 20.05.15 07:05
Оценка:
Здравствуйте, sushko, Вы писали:

U>>4) покрытия тестами


S>А что такое "покрытие тестами"? Речь идет о какой-то особенной системе автоматического тестирования со стоимостью в тысячи долларов за рабочее место или о чем-то более простом типа макроса ASSERT()?


Я обычно имею в виду юнит-тесты, функциональные и системные тесты.
www.blinnov.com
Re[8]: не получается перегрузить operator==
От: Vlad_SP  
Дата: 20.05.15 07:20
Оценка: +1
Здравствуйте, Кодт, Вы писали:

К>Но может быть и такой сценарий.

К>Код верифицирован "мамой клянус, здесь и здесь всегда одинаковая валюта", а кто-то из разработчиков вспомнил золотые слова Рейгана — "доверьяй но проверьяй".

Плохо он вспомнил. Или не те слова
Потому что "проверьяй" будет только в дебаге. Ага, в дебаге, в стерильно-чистых лабораторных условиях, у разработчиков все будет тип-топ. А в реальных условиях, то есть в релизе у заказчика, кто-нибудь обязательно догадается сравнить рубли с рупиями, — это уж даю гарантию, "мамой клянус!". И вот тогда наступит бабах.
Этот код, на самом деле, должен выглядеть как-то так:
bool operator==(const CMoney &other) const
    {
        ASSERT(m_iCurrencyID == other.m_iCurrencyID);
        if (m_iCurrencyID == other.m_iCurrencyID)
            return (m_fAmount == other.m_fAmount);
        else
            throw std::logic_error("Шеф, усе пропало! (с)");
    }

Выбрасывать, разумеется, можно что-то другое... зависит от дизайна системы.)

(Я бы посоветовал разработчикам помнить не только Рейгана, но и Джона Роббинса. Нет?)
Re[10]: не получается перегрузить operator==
От: sushko Россия  
Дата: 20.05.15 08:16
Оценка:
Здравствуйте, landerhigh, Вы писали:

S>>А что такое "покрытие тестами"? Речь идет о какой-то особенной системе автоматического тестирования со стоимостью в тысячи долларов за рабочее место или о чем-то более простом типа макроса ASSERT()?


L>Я обычно имею в виду юнит-тесты, функциональные и системные тесты.


Насколько я помню, юнит-тесты — это тестирование куска программы в отрыве от общего функционала; функциональные и системные тесты, если верить википедии — это тоже про процесс тестирования, т.е. отдельный от разработки процесс. То есть это не про ассерты, как мне кажется.

Ну вот не говорите же Вы "ребята, не ешьте мороженое, это вредно, лучше летайте на самолетах"? Мороженое и самолеты — это принципиально разные вещи, которые навряд ли заменят друг друга. Точно так же и тестирование не может заменить ассерты и наоборот?

Или под "тестами" Вы все же имели в виду не процесс тестирования как этап создания продукта, а что-то другое, какой-то конкретный механизм/макрос Си (или конкретно VisualC), которого я не знаю?
Бесплатный генератор отчетов для программ на C/C++
http://www.oxetta.com
Re[11]: не получается перегрузить operator==
От: landerhigh Пират  
Дата: 20.05.15 08:39
Оценка:
Здравствуйте, sushko, Вы писали:

L>>Я обычно имею в виду юнит-тесты, функциональные и системные тесты.


S>Насколько я помню, юнит-тесты — это тестирование куска программы в отрыве от общего функционала;


Юнит-тестирование — это доскональное автоматизированное (не автоматическое) тестирование функционала собственно юнита.

S>функциональные и системные тесты, если верить википедии — это тоже про процесс тестирования, т.е. отдельный от разработки процесс. То есть это не про ассерты, как мне кажется.


функциональные и системные тесты вполне могут быть частью процесса разработки.

S>Ну вот не говорите же Вы "ребята, не ешьте мороженое, это вредно, лучше летайте на самолетах"? Мороженое и самолеты — это принципиально разные вещи, которые навряд ли заменят друг друга. Точно так же и тестирование не может заменить ассерты и наоборот?


Не заменяет. Но одним из замеченных мной эффектов использования юнит-тестирования является то, что ассерты в коде становятся в общем случае ненужными.
Как бы на примере показать. В 80% случаев ассерт ставят на "вдруг указатель null" и похожие недопустимые предусловия. В процессе написание тестов обычно "это вдруг" уточняется до "только если программер совсем дурак", и тогда ставят явную защиту с исключением, а не ассерт. Чаще же выходит, что "существование объекта этого класса в случае, если некий указатель — null, не имеет смысла", в связи с чем перерабатывается логика класса.

S>Или под "тестами" Вы все же имели в виду не процесс тестирования как этап создания продукта, а что-то другое, какой-то конкретный механизм/макрос Си (или конкретно VisualC), которого я не знаю?


Юнит тестирование — это часть процесса разработки, выделять его как отдельный этап в цикле создания продукта не стоит.
www.blinnov.com
Re[9]: не получается перегрузить operator==
От: Erop Россия  
Дата: 20.05.15 22:59
Оценка:
Здравствуйте, landerhigh, Вы писали:

U>>1) ассерты только в дебаге


L>Вот ни разу не видел "повышения качества софта" от таких ассертов. Как правило, просто ставят ловушку на некий сценарий, подумать о корректной обработке которого ниасилили. Потом выплывают сюрпризы в релизе. Может быть, где-то их и используют обдуманно, но я еще не видел


Это наверное потому, что опыта мало...
Как минимум общепринятая практика состоит в том, что инварианты, и всякие пред- и пост-условия в них проверяют.
Плюсы такие, что это не только документирует код, но ещё, в отличии от камментов, автоматически актуально...
Ф общем Дейкстра со последователи типа рулит

U>>2) ассерты в релизе


L>Ой мама

При чём тут твоя мама?
Можно иметь два ассерта, один всегда проверяет условие, а второй тока в дебаге.
По умолчанию юзаем первый, а в случае если это накладно -- второй...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[10]: не получается перегрузить operator==
От: landerhigh Пират  
Дата: 21.05.15 08:00
Оценка:
Здравствуйте, Erop, Вы писали:

E>Это наверное потому, что опыта мало...


Линейку принес?

E>Как минимум общепринятая практика состоит в том, что инварианты, и всякие пред- и пост-условия в них проверяют.


Ассерт — это не проверка всяких ожидаемых условий. Это ловушка для условия, нарушенного в результате ошибки разработчика.

E>Плюсы такие, что это не только документирует код, но ещё, в отличии от камментов, автоматически актуально...


void myClass::myMethod(myParam param)
{
    ASSERT(m_pDataManager)
}


И так почти в каждом методе этого класса.
Документирует, как же.

E>Ф общем Дейкстра со последователи типа рулит


U>>>2) ассерты в релизе


E>При чём тут твоя мама?

E>Можно иметь два ассерта, один всегда проверяет условие, а второй тока в дебаге.

Давай сначала разберемся с терминологией. Ассерт в классическом его виде — это остановка с выбросом в отладчик или тупо падение. Если оно не приводит к падению, то это не ассерт, а именно что проверка и обработка пред- и пост-условий.
Так вот, имхо практически единственное оправданное применение ассерту в релизе состоит в том, чтобы проверять пред- и пост-условия при работе со сторонней либой, которая вроде бы и обещает вести себя хорошо, но тут именно что "доверяй, но проверяй".

E>По умолчанию юзаем первый, а в случае если это накладно -- второй...


Мы вот вообще дебажные сборки практически не используем.
www.blinnov.com
Re[11]: не получается перегрузить operator==
От: Erop Россия  
Дата: 21.05.15 10:35
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Ассерт — это не проверка всяких ожидаемых условий. Это ловушка для условия, нарушенного в результате ошибки разработчика.

Ты это, с концепцией процедурного программирования знаком? В чьей формулировке?
Что такое предусловие и постусловие кода знаешь? Что такое инвариант цикла?

E>>Плюсы такие, что это не только документирует код, но ещё, в отличии от камментов, автоматически актуально...


L>И так почти в каждом методе этого класса.

1) Не факт, что это образец того, как надо использовать ассерты.
2) "Почти" значит, что не в каждом.
L>Документирует, как же.
Ну в принципе да. Показывает, в каких их методов требуется, что бы m_pDataManager был не ноль...

L>Давай сначала разберемся с терминологией. Ассерт в классическом его виде — это остановка с выбросом в отладчик или тупо падение. Если оно не приводит к падению, то это не ассерт, а именно что проверка и обработка пред- и пост-условий.

Бывают разные библиотеки assert'ов, во-первых, и разные требования на продукт/код, во-вторых.
Иногда упасть по авосту, но ничего не испортить, если не уверен не худший вариант, вообще-то.

L>Так вот, имхо практически единственное оправданное применение ассерту в релизе состоит в том, чтобы проверять пред- и пост-условия при работе со сторонней либой, которая вроде бы и обещает вести себя хорошо, но тут именно что "доверяй, но проверяй".


Почему только со сторонней? Чем совя либа лучше, чем чужая?
А если есть большая контора, разные части которой разрабатывают разные подсистемы изделия? Там какие либы "свои", а какие "чужие"?
Ну и вообще, не понятно, что мешает не доверять вообще никакому коду априори, если уж ты умеешь не доверять сторонним либам?
Чем проверки пред/пост условий и инвариантов объектов и циклов вредят? Производительности? Ну те, которые реально вредят, можно делать только в дебажной сборке, а 99% не вредят жеж.

L>Мы вот вообще дебажные сборки практически не используем.

Ну это же ваша особенность? Другие используют.

Кстати, а инженерные сборки? (ну, то есть, они как релизные, но с более развитым инструментарием для настройки и логирования)?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[12]: не получается перегрузить operator==
От: landerhigh Пират  
Дата: 21.05.15 12:09
Оценка:
Здравствуйте, Erop, Вы писали:

L>>Ассерт — это не проверка всяких ожидаемых условий. Это ловушка для условия, нарушенного в результате ошибки разработчика.

E>Ты это, с концепцией процедурного программирования знаком? В чьей формулировке?
E>Что такое предусловие и постусловие кода знаешь? Что такое инвариант цикла?

Ты вообще в состоянии общаться без перехода на личности?

L>>И так почти в каждом методе этого класса.

E>1) Не факт, что это образец того, как надо использовать ассерты.

99% случаев, однако.

E>2) "Почти" значит, что не в каждом.


Конечно. В тех, которые не обращаются по данному указателю, ассерт не добавили. Подумали.

L>>Документирует, как же.

E>Ну в принципе да. Показывает, в каких их методов требуется, что бы m_pDataManager был не ноль...

Документирует то, что присутствует серьезный архитектурный косяк, который попытались поправить костылем.

L>>Давай сначала разберемся с терминологией. Ассерт в классическом его виде — это остановка с выбросом в отладчик или тупо падение. Если оно не приводит к падению, то это не ассерт, а именно что проверка и обработка пред- и пост-условий.

E>Бывают разные библиотеки assert'ов, во-первых, и разные требования на продукт/код, во-вторых.

Много чего бывает.

E>Иногда упасть по авосту, но ничего не испортить, если не уверен не худший вариант, вообще-то.


Упасть по необработанному исключению? Конечно.
Натолкать повсюду ассертов в надежде, что во время тестирования все косяки программеров вылезут в высшей степени наивно. Ну и классическое — переключились в релиз и ничего не работает вообще.

L>>Так вот, имхо практически единственное оправданное применение ассерту в релизе состоит в том, чтобы проверять пред- и пост-условия при работе со сторонней либой, которая вроде бы и обещает вести себя хорошо, но тут именно что "доверяй, но проверяй".

E>Почему только со сторонней? Чем совя либа лучше, чем чужая?

Своя либа у нас имеет гарантию поведения. Проверенную специальными тестами. А у вас?

E>Ну и вообще, не понятно, что мешает не доверять вообще никакому коду априори, если уж ты умеешь не доверять сторонним либам?


Можно еще и процессору перестать доверять, да. Проверяй каждую операцию

E>Чем проверки пред/пост условий и инвариантов объектов и циклов вредят? Производительности? Ну те, которые реально вредят, можно делать только в дебажной сборке, а 99% не вредят жеж.


Где тут циклы и постусловия? Ты вообще оригинальное сообщение читал? Там релизная сборка молча прожует сравнение рублей с рупиями.

L>>Мы вот вообще дебажные сборки практически не используем.

E>Ну это же ваша особенность? Другие используют.

Все же я склонен думать, что это наше преимущество.

E>Кстати, а инженерные сборки? (ну, то есть, они как релизные, но с более развитым инструментарием для настройки и логирования)?


Инженерные сборки, которые в результате различий в коде меняют тайминги, вследствие чего замеченные тестерами или клиентами проблемы перестают воспроизводиться, зато появляются новые?
У нас развитое и местами даже избыточное инженерное логгирование включено в стандартные релизы и может включаться-выключаться на лету.
Отладочного логгирования практически не осталось, после внедрения TDD и автоматического тестирования на каждом этапе нужда в нем отпала.
www.blinnov.com
Re[13]: не получается перегрузить operator==
От: Erop Россия  
Дата: 21.05.15 12:23
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Ты вообще в состоянии общаться без перехода на личности?

Почему переход? Я хочу понять, на каком языке с тобйо общаться просто. Судя по обиде, ты в курсе того, что я прашивал. Так?

L>Документирует то, что присутствует серьезный архитектурный косяк, который попытались поправить костылем.

Не понял, почему косяк? Почему кстылём? А если предусловие "такое-то число должно быть чётным", то тоже косяк?

L>Упасть по необработанному исключению? Конечно.

Не всегда можно использовать исключения...

Вообще, что конкретно делает ассерт в случае провала -- вопрос технический. принципиально он меняет мало.
E>>Почему только со сторонней? Чем совя либа лучше, чем чужая?
L>Своя либа у нас имеет гарантию поведения. Проверенную специальными тестами. А у вас?
Не всё можно тестами проверить. ассерты, это нечто дополнительное к тестам просто.

L>Где тут циклы и постусловия? Ты вообще оригинальное сообщение читал? Там релизная сборка молча прожует сравнение рублей с рупиями.

Там сделано нехорошо. Как хорошо, я уже написал -- по умолчанию использовать такой assert, который в любой сборке авост устроит.

L>Все же я склонен думать, что это наше преимущество.

Ну разные задачи бывают, разные производственные циклы и т. д...

L>Инженерные сборки, которые в результате различий в коде меняют тайминги, вследствие чего замеченные тестерами или клиентами проблемы перестают воспроизводиться, зато появляются новые?

Ну кривые руки могут многое. Это ты прав.

L>У нас развитое и местами даже избыточное инженерное логгирование включено в стандартные релизы и может включаться-выключаться на лету.

Не всегда есть желание отдавать инженерную сборку клиенту, вообще-то. Она облегчает реверс-инжениринг...

L>Отладочного логгирования практически не осталось, после внедрения TDD и автоматического тестирования на каждом этапе нужда в нем отпала.

Значит код не наукоёмкий.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[14]: не получается перегрузить operator==
От: landerhigh Пират  
Дата: 21.05.15 12:45
Оценка:
Здравствуйте, Erop, Вы писали:

L>>Документирует то, что присутствует серьезный архитектурный косяк, который попытались поправить костылем.

E>Не понял, почему косяк? Почему кстылём? А если предусловие "такое-то число должно быть чётным", то тоже косяк?

Мы о разных вещах говорим.

Означенный мной паттерн применения ассертов цветет там, где архитектура допускает наличие объекта-зомби, который внешне вроде живой, но попытка его позвать вызовет срабатывание фугаса. Как правило, это наблюдается там, где инициализация объекта размазана во времени и по коду. Это серьезный косяк, который тем не менее довольно легко фиксится.
Если объект существует, он обязан находиться в работоспособном состоянии и не должен заставлять обращающихся к нему сначала справляться о состоянии его потрохов.
И нет, ассерт — это не то же самое, что и выброс исключения в случае, если объект временно болен.

Ты же говоришь о проверке условий, передаваемых в подпрограмму. Это много разных разниц.

L>>Упасть по необработанному исключению? Конечно.

E>Не всегда можно использовать исключения...

Мы не в священных войнах, есличо.

L>>Своя либа у нас имеет гарантию поведения. Проверенную специальными тестами. А у вас?

E>Не всё можно тестами проверить. ассерты, это нечто дополнительное к тестам просто.

Вообще-то проверить тестами можно практически все. Вопрос только в затратах.
Но ассерты не дополняют тесты никак.

L>>Где тут циклы и постусловия? Ты вообще оригинальное сообщение читал? Там релизная сборка молча прожует сравнение рублей с рупиями.

E>Там сделано нехорошо. Как хорошо, я уже написал -- по умолчанию использовать такой assert, который в любой сборке авост устроит.

А я написал, что сравнение разных валют в первую очередь вопрос архитектуры.

L>>Инженерные сборки, которые в результате различий в коде меняют тайминги, вследствие чего замеченные тестерами или клиентами проблемы перестают воспроизводиться, зато появляются новые?

E>Ну кривые руки могут многое. Это ты прав.

Палишься. Расскажи, чем нужно выпрямлять руки, чтобы включение дополнительного кода в исполняемом файле гарантированно не повлияло на тайминги?

L>>Отладочного логгирования практически не осталось, после внедрения TDD и автоматического тестирования на каждом этапе нужда в нем отпала.

E>Значит код не наукоёмкий.

Кто о чем, а Erop опять о линейке
www.blinnov.com
Re: не получается перегрузить operator==
От: __kot2  
Дата: 21.05.15 12:53
Оценка:
Здравствуйте, sushko, Вы писали:
S>У меня в VisualC 10 есть класс с перегруженным operator==. Когда я в коде пишу сравнение двух экземпляров этого класса, в отладчике я вижу, что в перегруженный operator== выполнение программы просто не заходит, считая результат операции всегда TRUE. Почему?
когда конструктор какого-то обьекта не explicit, то обьект может ниажидана откаститься к этому обьекту. могу предположить что тут та же история — ператор == вызывается для другого класса, к которому все хитро кастится
Re[15]: не получается перегрузить operator==
От: Erop Россия  
Дата: 21.05.15 13:22
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Палишься. Расскажи, чем нужно выпрямлять руки, чтобы включение дополнительного кода в исполняемом файле гарантированно не повлияло на тайминги?

Без понятия. IMHO тут горматого могила исправит...
Но вы же как-то свои развитые логи пишете?

Пример инженерного кода: можно вызвать какой-то инженерный режим и там поменять какие-то настройки, которые в релизной версии приколочены гвоздями.
Где тут нужно выпрямит руки, что бы тайминги не ушли?

L>Кто о чем, а Erop опять о линейке

При чём тут линейка? Есть задачи когда всё известно, что должна делать программа, надо просто реализовать. Ну 1С например. Они ненаукоёмкие.
А есть такие, где неизвестно что и как должна делать программа, известен, например, только результат, и то в общих чертах. А как и что конкретно надо делать -- предмет для НИОКРа...
Ну, угадыватель каши, которая сегодня понравится ребёнку, например.
Тогда разработка наукоёмкая.

Почему ты считаешь, что одна круче другой?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.