опять про assert-ы
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 02.04.08 13:02
Оценка: +5
Здравствуйте, _FRED_, Вы писали:

_FR> пользователь моих биллиотек, для которого ассерт в _моём_ коде — означает (и правильно!) _мою_ ошибку,


почему правильно-то? всю жизнь, и правильно, assert в коде библиотеки означал, что ее неправильно используют, не так как задумал автор
... << RSDN@Home 1.2.0 alpha 4 rev. 1061>>

02.04.08 19:11: Ветка выделена из темы А вот такое решение?
Автор: vit0s
Дата: 02.04.08
— Odi$$ey
02.04.08 19:16: Перенесено модератором из '.NET' — Odi$$ey
assert
Re: опять про assert-ы
От: _FRED_ Черногория
Дата: 02.04.08 13:27
Оценка: +1
Здравствуйте, Odi$$ey, Вы писали:

_FR>> пользователь моих биллиотек, для которого ассерт в _моём_ коде — означает (и правильно!) _мою_ ошибку,


OE>почему правильно-то? всю жизнь, и правильно, assert в коде библиотеки означал, что ее неправильно используют, не так как задумал автор


Ну это только си++-нутые так делают (кстати, а как часто в stl ассерты написаны и по каким случаям) (я больше нигде не видел :о)), потому что по-другому не хотят и не могут. Ну не принято почему-то у С++ — ников проверять аргументы при вызове (кстати, почему? банальная лень? экономия тактов на сравнениях?), а тут, в .NET, принято и этим надо пользоваться.

В чём отличие исключения от ассерта? Для меня — именно то, что ассертом я проверяю собственные ошибки (нарушение инвариантов) или, например, то, что системные\сторонние библиотеки делают именно то, что сказано у них в документации\проверено на личном опыте, то есть ассерты срабатывают тогда, когда надо менять тот код, в котором написан ассерт. А для тех ситуаций, когда мне надо сказать, что меня используют не так, как я ожидаю, я бросаю исключения "наружу". Мне это кажется правильным. Интересно, как поступают другие?

Кстати, не изменяет ли мне склероз, и не писал ли об этом Майерс и Со? Нет под рукой книги…

P.S. Может, отделим ветку?
... << RSDN@Home 1 alpha 3 rev. 0>>
Help will always be given at Hogwarts to those who ask for it.
Re[2]: опять про assert-ы
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 02.04.08 14:37
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>P.S. Может, отделим ветку?


да ладно. Обсуждали уж assert-ы не раз Re[16]: Необходимость ASSERT
Автор: Odi$$ey
Дата: 19.10.05
, Re[5]: Проверка данных на нижнем уровне или на верхнем?
Автор: Odi$$ey
Дата: 12.02.06


коротко:
>ассерты срабатывают тогда, когда надо менять тот код, в котором написан ассерт.
для меня — менять надо тот код, который использует код со сработавшим ASSERT-ом
... << RSDN@Home 1.2.0 alpha 4 rev. 1061>>
Re[3]: опять про assert-ы
От: _FRED_ Черногория
Дата: 02.04.08 14:41
Оценка:
Здравствуйте, Odi$$ey, Вы писали:

OE>коротко:

>>ассерты срабатывают тогда, когда надо менять тот код, в котором написан ассерт.
OE>для меня — менять надо тот код, который использует код со сработавшим ASSERT-ом

То есть, код начиная от того метода, в котором вызван метод асерта, а не начиная с того, где ассерт объявлен\сработал?
... << RSDN@Home 1 alpha 3 rev. 0>>
Help will always be given at Hogwarts to those who ask for it.
Re: опять про assert-ы
От: Severn Россия  
Дата: 02.04.08 15:06
Оценка: +1
Здравствуйте, Odi$$ey, Вы писали:

OE>почему правильно-то? всю жизнь, и правильно, assert в коде библиотеки означал, что ее неправильно используют, не так как задумал автор


А тестировать-то как? В смысле юнит-тестировать. Сидеть и на каждом из сотни тестов мышкой закрывать ассертовские мессаги?
Re[4]: опять про assert-ы
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 02.04.08 15:08
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>То есть, код начиная от того метода, в котором вызван метод асерта, а не начиная с того, где ассерт объявлен\сработал?


не понял. Еще раз:

если есть:

void somefunc(int i)
{
   assert(i!=0);
}

то

somefunc(n);

надо заменить на

if(n!=0)
    somefunc(n);
else
    ...
... << RSDN@Home 1.2.0 alpha 4 rev. 1061>>
Re[2]: опять про assert-ы
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 02.04.08 15:10
Оценка:
Здравствуйте, Severn, Вы писали:

S>А тестировать-то как? В смысле юнит-тестировать. Сидеть и на каждом из сотни тестов мышкой закрывать ассертовские мессаги?


тестируй release, assert он только для разработчика, в debug-е
... << RSDN@Home 1.2.0 alpha 4 rev. 1061>>
Re[3]: опять про assert-ы
От: Left2 Украина  
Дата: 02.04.08 15:23
Оценка:
S>>А тестировать-то как? В смысле юнит-тестировать. Сидеть и на каждом из сотни тестов мышкой закрывать ассертовские мессаги?
OE>тестируй release, assert он только для разработчика, в debug-е
Не обязательно release, можно просто для найттестов брать билд в котором ассёрты не показывают окошко, а пишут проблему в лог.
В целом я о том что, Ассерт != окошко.
... << RSDN@Home 1.2.0 alpha rev. 717>>
Re: опять про assert-ы
От: _pk_sly  
Дата: 02.04.08 15:24
Оценка:
Здравствуйте, Odi$$ey, Вы писали:

OE>почему правильно-то? всю жизнь, и правильно, assert в коде библиотеки означал, что ее неправильно используют, не так как задумал автор


нет. в этих случаях должен быть возврат ошибки (для любителей тонких извращений — exception)
Re[2]: опять про assert-ы
От: Mamut Швеция http://dmitriid.com
Дата: 02.04.08 15:26
Оценка: 21 (3) +2
_FR>Ну не принято почему-то у С++ — ников проверять аргументы при вызове (кстати, почему? банальная лень? экономия тактов на сравнениях?), а тут, в .NET, принято и этим надо пользоваться.

Агресивное vs. защитное (agressive vs. defensive) программирование. В агрессивном вызывающая функция должна заботиться о правильности передаваемых параметров, а вызываемая — вылетать нафиг при первом же неудобном случае

Иначе никаких if-ов и try-catch-ев не напасешься
... << RSDN@Home 1.2.0 alpha 3 rev. 968>>


dmitriid.comGitHubLinkedIn
Re[2]: опять про assert-ы
От: _pk_sly  
Дата: 02.04.08 15:28
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Ну не принято почему-то у С++ — ников проверять аргументы при вызове


это, видать, учебные С++ники
Re[2]: опять про assert-ы
От: neFormal Россия  
Дата: 02.04.08 15:51
Оценка:
Здравствуйте, _pk_sly, Вы писали:

OE>>почему правильно-то? всю жизнь, и правильно, assert в коде библиотеки означал, что ее неправильно используют, не так как задумал автор

__>нет. в этих случаях должен быть возврат ошибки (для любителей тонких извращений — exception)

при передаче в конструктор параметром указателя возврат ошибки выглядит странно.. ассерт там имхо более логичен..

лично я использую assert-ы для проверки деталей, ошибки в которых несовместимы с "жизнью" приложения..
коды ошибок — если хочу анализировать результат выполнения..
исключения — если ошибка может быть несовместима с "жизнью" приложения.. а может и не быть Либо в местах, где в начале происходит что то "ошибковозможное", в середине может случиться какая нибудь проблема, а в конце от этого надо красиво избавиться..
...coding for chaos...
Re[2]: опять про assert-ы
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 02.04.08 16:29
Оценка:
Здравствуйте, _pk_sly, Вы писали:

OE>>почему правильно-то? всю жизнь, и правильно, assert в коде библиотеки означал, что ее неправильно используют, не так как задумал автор

__>нет. в этих случаях должен быть возврат ошибки (для любителей тонких извращений — exception)

а когда же нужны assert-ы?
... << RSDN@Home 1.2.0 alpha 4 rev. 1061>>
Re[3]: опять про assert-ы
От: _pk_sly  
Дата: 02.04.08 16:47
Оценка: 2 (1) +2 -1
Здравствуйте, Odi$$ey, Вы писали:

OE>а когда же нужны assert-ы?


примерно в таких ситуациях:

a = b;
assert(a == b);


естественно, что это — упрощённая модель, случаи бывают гораздо более витиеватые, разбросанные по функциям, классам и компонентам.

более того, всегда надо помнить что assert — это макрос, который в релизе превращается в ничто!
он обязан не выполнять никакой полезной работы и ошибки через него отлавливаются только в debug-компиляции. если дополнительно требуется проверка условия, она должна быть сделана отдельно. например так:

a = b;
assert(a == b);
if (a != b) { return error; }


это добавляет стабильности релизному коду, одновременно помогая поймать ошибки в дебаге.
Re[3]: опять про assert-ы
От: Severn Россия  
Дата: 02.04.08 19:01
Оценка:
Здравствуйте, Odi$$ey, Вы писали:

OE>тестируй release, assert он только для разработчика, в debug-е


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

Я совсем не против ассертов, просто все дело в том, что из себя представляет их реализация. Если это — классическая модальная мессага которая может вывалиться где-нибудь на веб сервере, то тогда втопку. Можно, как Left2
Автор: Left2
Дата: 02.04.08
логировать, но имхо это тоже не совсем то что нужно. Из-за лога тест не упадет. Имхо лучший вариант — обычное исключение.

Тут дельные мысли по этому поводу.
Re[4]: опять про assert-ы
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 03.04.08 03:20
Оценка: +2
Здравствуйте, Severn, Вы писали:

OE>>тестируй release, assert он только для разработчика, в debug-е

S>А смысл тогда в таких ассертах, если они в тестах будут отключены? Если мой код использует библиотеку криво, я _всегда_ должен получать ошибку — и в дебаге и релизе.

смысл assert-a — "визуализация" и контроль в процессе разработки неких условий, на которые полагается код. Если у тебя функция принимает int ты же не пытаешься тестировать ее заталкивая ей DateTime, string и дальше по списку. Точно также, если на входе функции стоит assert(i != 0) _бессмысленно_ "тестировать" ее передавая ей 0, получать кучу модальных окон и переживать по этому поводу. Срабатываний assert-ов вообще не должно быть, в отличии от результатов проверок входных параметров и еще чего-бы то ни было в runtime.

Обнаружение неправильных параметров в процессе работы — нормальная ситуация, обнаружили — ура, тест прошел, программа работает. Если сработал assert — все, можно сливать воду, программа уже принципиально работает неправильно.

S>Я совсем не против ассертов, просто все дело в том, что из себя представляет их реализация.


это совершенно вторичный вопрос
... << RSDN@Home 1.2.0 alpha 4 rev. 1061>>
Re: опять про assert-ы
От: andy1618 Россия  
Дата: 03.04.08 06:05
Оценка: -1
_FR>> пользователь моих биллиотек, для которого ассерт в _моём_ коде — означает (и правильно!) _мою_ ошибку,
OE>почему правильно-то? всю жизнь, и правильно, assert в коде библиотеки означал, что ее неправильно используют, не так как задумал автор

Всё-таки, в большинстве случаев Assert в коде библиотеки должен означать ошибку именно _внутри_ библиотеки (нарушение инвариантов, постусловий и т.п.), которую придётся исправлять её автору

Что же касается расстановки Assert-ов для контроля входных параметров — это разумно делать только для внутрибиблиотечных вызовов, чтобы зафиксировать ситуацию "автор библиотеки — М." (а не "пользователь — М.")
На внешние же вызовы Assert-ы на входе ставить не стоит, хотя бы из соображений unit-тестирования debug-версии.

Всё ИМХО.
Re[5]: опять про assert-ы
От: Severn Россия  
Дата: 03.04.08 06:45
Оценка:
Здравствуйте, Odi$$ey, Вы писали:

OE>смысл assert-a — "визуализация" и контроль в процессе разработки неких условий, на которые полагается код. Если у тебя функция принимает int ты же не пытаешься тестировать ее заталкивая ей DateTime, string и дальше по списку.


Это уже работа для компилятора, а не для ассерта...

S>>Я совсем не против ассертов, просто все дело в том, что из себя представляет их реализация.


OE>это совершенно вторичный вопрос


Эмм...этот вопрос может привести к полному отказу от ассертов — когда они реализованы криво.

Если в коде стоит ASSERT(...), то библиотека должна упасть при неправильном испльзовании. И максимально четко объяснить почему она упала.
Ок, замечательно. Два НО:
1. Но это должно работать и в релизе и в дебаге. Если из-за невнимательного разработчика/тестера/ПМа или еще хз кого, баг просочится на продакшен, то пусть лучше прога со свистом упадет, чем криво посчитает дебеты/кредиты.
2. Но только не вываливать UI элементы в месте вызова ASSERT. Два контрпримера — проблемы с юнит тестированием, проблемы с удаленным запуском на всякого рода серверах.

по поводу #2, скажем, в .нетовской реализации ассерта, можно убрать месседж бокс и включить логирование. Но это не приведет к падению программы. имхо лехче просто кинуть специальный экспешен.

public class Assert 
{
public static void That(bool condition) 
{
if (!condition) throw new AssertException();
}
Re[2]: опять про assert-ы
От: TK Лес кывт.рф
Дата: 03.04.08 07:02
Оценка: +1
Здравствуйте, Severn, Вы писали:

OE>>почему правильно-то? всю жизнь, и правильно, assert в коде библиотеки означал, что ее неправильно используют, не так как задумал автор


S>А тестировать-то как? В смысле юнит-тестировать. Сидеть и на каждом из сотни тестов мышкой закрывать ассертовские мессаги?


Если для определенного кода есть юнит тест то, это значит, что данное использование было задумано (если конечно, отбросить ситуации, когда тесты пишутся в беспамятстве). следовательно, для задуманного поведения ассертов быть не должно.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[3]: опять про assert-ы
От: Severn Россия  
Дата: 03.04.08 07:32
Оценка:
Здравствуйте, TK, Вы писали:

TK>Здравствуйте, Severn, Вы писали:


S>>А тестировать-то как? В смысле юнит-тестировать. Сидеть и на каждом из сотни тестов мышкой закрывать ассертовские мессаги?


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


Может я чего не понял. Но хочу я скажем протестировать мой Метод:

public void Метод()
{
MyBLObj res = посчитайЧтонибудь();
Assert.That(res != null);
отдайКудаНибудь(res);
}

private MyBLObj посчитайЧтонибудь()
{
//...
}
private void отдайКудаНибудь(MyBLObj obj)
{
//...
}


Ассерт обязаетльно когда-нибудь сработает.

Кроме того, в в исходном посте
Автор: Odi$$ey
Дата: 02.04.08
речь о вызове внешних библиотек. Библиотеку я использую из некой своей бизнес-логике. Само-собой где-нибудь она будет исользоватья некорректно и из тестов моих объектов повалятся ассерты.
Грубо говоря, что было бы, если бы .нетовские классы вместо эксепшена кидали ассерт? Думаю, пациентов с расстроенной психикой определенно прибавилось.
Re[4]: опять про assert-ы
От: Mamut Швеция http://dmitriid.com
Дата: 03.04.08 08:35
Оценка:
S>Кроме того, в в исходном посте
Автор: Odi$$ey
Дата: 02.04.08
речь о вызове внешних библиотек. Библиотеку я использую из некой своей бизнес-логике. Само-собой где-нибудь она будет исользоватья некорректно и из тестов моих объектов повалятся ассерты.

S>Грубо говоря, что было бы, если бы .нетовские классы вместо эксепшена кидали ассерт? Думаю, пациентов с расстроенной психикой определенно прибавилось.

Исключения позволяют не заботиться о правильности передаваемых результатов — подумаешь, исключение, ща на него try-catch накинем, значение по умолчанию возвращать будем
... << RSDN@Home 1.2.0 alpha 3 rev. 968>>


dmitriid.comGitHubLinkedIn
Re[5]: опять про assert-ы
От: Severn Россия  
Дата: 03.04.08 08:55
Оценка: +2 :)
Здравствуйте, Mamut, Вы писали:

S>>Кроме того, в в исходном посте
Автор: Odi$$ey
Дата: 02.04.08
речь о вызове внешних библиотек. Библиотеку я использую из некой своей бизнес-логике. Само-собой где-нибудь она будет исользоватья некорректно и из тестов моих объектов повалятся ассерты.

S>>Грубо говоря, что было бы, если бы .нетовские классы вместо эксепшена кидали ассерт? Думаю, пациентов с расстроенной психикой определенно прибавилось.

M>Исключения позволяют не заботиться о правильности передаваемых результатов — подумаешь, исключение, ща на него try-catch накинем, значение по умолчанию возвращать будем


Ну...от дурака защиту не придумаешь. Ассерты же тоже задавить можно — подумаешь DefaultTraceListener убрать
Re[4]: опять про assert-ы
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 03.04.08 10:06
Оценка:
Здравствуйте, Severn, Вы писали:

S>[c#]

S>public void Метод()
S>{
S>MyBLObj res = посчитайЧтонибудь();
S>Assert.That(res != null);
S>отдайКудаНибудь(res);
S>}

Assert — это утверждение, в данном случае — это утверждение, что res никогда не может быть равно null

S>Ассерт обязаетльно когда-нибудь сработает.


значит в логике посчитайЧтонибудь() есть ошибка и ее надо править. И что?

S>Кроме того, в в исходном посте
Автор: Odi$$ey
Дата: 02.04.08
речь о вызове внешних библиотек. Библиотеку я использую из некой своей бизнес-логике. Само-собой где-нибудь она будет исользоватья некорректно и из тестов моих объектов повалятся ассерты.


ну, будешь править бизнес логику так, чтоб assert-ов не было, и что?
... << RSDN@Home 1.2.0 alpha 4 rev. 1061>>
Re[5]: опять про assert-ы
От: Severn Россия  
Дата: 03.04.08 10:45
Оценка:
Здравствуйте, Odi$$ey, Вы писали:

OE>Здравствуйте, Severn, Вы писали:


OE>Assert — это утверждение, в данном случае — это утверждение, что res никогда не может быть равно null


S>>Ассерт обязаетльно когда-нибудь сработает.


OE>значит в логике посчитайЧтонибудь() есть ошибка и ее надо править. И что?


С этим никто не спорит.

S>>Кроме того, в в исходном посте
Автор: Odi$$ey
Дата: 02.04.08
речь о вызове внешних библиотек. Библиотеку я использую из некой своей бизнес-логике. Само-собой где-нибудь она будет исользоватья некорректно и из тестов моих объектов повалятся ассерты.


OE>ну, будешь править бизнес логику так, чтоб assert-ов не было, и что?


Читай плз внимательнее о чем речь шла. При юнит тесте метода вылетит ассерт, если ассерт покажет UI сообщение, то протестировать метод не получится.
Re[4]: опять про assert-ы
От: ShaggyOwl Россия http://www.rsdn.org
Дата: 03.04.08 12:29
Оценка:
Здравствуйте, _pk_sly, Вы писали:

__>более того, всегда надо помнить что assert — это макрос, который в релизе превращается в ничто!

__>он обязан не выполнять никакой полезной работы и ошибки через него отлавливаются только в debug-компиляции. если дополнительно требуется проверка условия, она должна быть сделана отдельно. например так:

__>
__>a = b;
__>assert(a == b);
__>if (a != b) { return error; }
__>


__>это добавляет стабильности релизному коду, одновременно помогая поймать ошибки в дебаге.


Наблюдение вскользь. Если у тебя присутствует код вида
if (a != b) { return error; }

или
if (a != b) { throw error; }

и после появления ошибки ты не можешь точно указать строку (и условия) при которой произошла ошибка, то можно говорить о том, что в коде есть проблема. Аргументация очевидна — толку с такой диагностики ноль.
Если ты можешь указать строку (и условия), то ассерт просто не нужен.
Хорошо там, где мы есть! :)
Re[5]: опять про assert-ы
От: _pk_sly  
Дата: 03.04.08 12:46
Оценка: +2
Здравствуйте, ShaggyOwl, Вы писали:

SO>и после появления ошибки ты не можешь точно указать строку (и условия) при которой произошла ошибка, то можно говорить о том, что в коде есть проблема. Аргументация очевидна — толку с такой диагностики ноль.

SO>Если ты можешь указать строку (и условия), то ассерт просто не нужен.

ещё раз.
assert — это один из способов отладки кода в debug-версии.
после того, как погоняли debug и решили что код ведёт себя корректно, выпускается release, где эти проверки отсутствуют, поскольку они просто не нужны — код ведёт себя корректно.

assert + if (либо throw) — это, скорее, затычка "на всякий пожарный", которая, вообще-то, в нормальном режиме работы никогда не должна срабатывать. однако, она может спасти клиента от невыявленного бага. а может и не спасти.

тут уже надо смотреть что важнее: если отладиться на клиенте, пусть он кликает на "send report"; если стабильность, то по возможности, программа должна работать из любых положений, само-восстанавливаться, само-перезапускаться и т.д.

софт бывает очень разный и решать он может очень разные задачи.
Re[6]: опять про assert-ы
От: ShaggyOwl Россия http://www.rsdn.org
Дата: 03.04.08 13:13
Оценка:
Здравствуйте, _pk_sly, Вы писали:

ещё раз. (c)

__>assert + if (либо throw) — это, скорее, затычка "на всякий пожарный", которая, вообще-то, в нормальном режиме работы никогда не должна срабатывать. однако, она может спасти клиента от невыявленного бага. а может и не спасти.


Если у тебя в коде стоит ассерт и следующей строкой проверяется такое же условие (вне зависимости от последствий), то у тебя одно и то же условие в дебаге проверяется два раза подряд. Зачем — непонятно.
Хорошо там, где мы есть! :)
Re[7]: опять про assert-ы
От: _pk_sly  
Дата: 03.04.08 13:58
Оценка:
Здравствуйте, ShaggyOwl, Вы писали:

SO>Если у тебя в коде стоит ассерт и следующей строкой проверяется такое же условие (вне зависимости от последствий), то у тебя одно и то же условие в дебаге проверяется два раза подряд. Зачем — непонятно.


за тем, что в релизе ассерта уже не будет
а дебаг делается с одной единственной целью — выпустить релиз.

конечно, для таких случаев можно написать assert2, который в дебаге будет простым ассертом, а в релизе будет проверкой, которая что-то делает в плохом случае.
не вопрос.

тут проблема в другом. как правило, assert проверяет целостность данных. если он не прошёл, то программа, как правило, не жилец в любом случае.
возможности корректного восстановления, как правило, нет.
Re[3]: опять про assert-ы
От: _FRED_ Черногория
Дата: 03.04.08 21:10
Оценка:
Здравствуйте, Odi$$ey, Вы писали:

_FR>>P.S. Может, отделим ветку?


OE>да ладно. Обсуждали уж assert-ы не раз Re[16]: Необходимость ASSERT
Автор: Odi$$ey
Дата: 19.10.05
, Re[5]: Проверка данных на нижнем уровне или на верхнем?
Автор: Odi$$ey
Дата: 12.02.06


OE>коротко:

>>ассерты срабатывают тогда, когда надо менять тот код, в котором написан ассерт.
OE>для меня — менять надо тот код, который использует код со сработавшим ASSERT-ом

Почитал, но ни где не нашёл твоих объяснений своей позиции Только "должно быть так и так", но не почему. В первую очередь мне любопытно: где разница между асертом и исключением?
... << RSDN@Home 1.2.0 alpha 4 rev. 1048>>
Help will always be given at Hogwarts to those who ask for it.
Re[5]: опять про assert-ы
От: _FRED_ Черногория
Дата: 03.04.08 21:13
Оценка:
Здравствуйте, Odi$$ey, Вы писали:

_FR>>То есть, код начиная от того метода, в котором вызван метод асерта, а не начиная с того, где ассерт объявлен\сработал?


OE>не понял. Еще раз:

OE>если есть:
OE>void somefunc(int i)
OE>{
OE>   assert(i!=0);
OE>}

OE>то
OE>somefunc(n);

OE>надо заменить на
OE>if(n!=0)
OE>    somefunc(n);
OE>else
OE>    ...


Нет, у меня такой ситуации в принципе быть не может, потому что в данном примере условие ассерта зависит от внешний параметров. Я считаю, что асерт — это утверждение. То есть "должно быть так!" и восклицательный знак. А если "не так", тозначит не прав тот, кто утверждение поставил. И в этом отличие асерта от исключения.
... << RSDN@Home 1.2.0 alpha 4 rev. 1048>>
Help will always be given at Hogwarts to those who ask for it.
Re[3]: опять про assert-ы
От: _FRED_ Черногория
Дата: 03.04.08 21:17
Оценка:
Здравствуйте, Mamut, Вы писали:

_FR>>Ну не принято почему-то у С++ — ников проверять аргументы при вызове (кстати, почему? банальная лень? экономия тактов на сравнениях?), а тут, в .NET, принято и этим надо пользоваться.


M>Агресивное vs. защитное (agressive vs. defensive) программирование. В агрессивном вызывающая функция должна заботиться о правильности передаваемых параметров, а вызываемая — вылетать нафиг при первом же неудобном случае


Спасибо, поищу.

M>Иначе никаких if-ов и try-catch-ев не напасешься


Хм: в дотнете прекрасно напасаются
... << RSDN@Home 1.2.0 alpha 4 rev. 1048>>
Help will always be given at Hogwarts to those who ask for it.
Re[4]: опять про assert-ы
От: _FRED_ Черногория
Дата: 03.04.08 21:18
Оценка:
Здравствуйте, Left2, Вы писали:

S>>>А тестировать-то как? В смысле юнит-тестировать. Сидеть и на каждом из сотни тестов мышкой закрывать ассертовские мессаги?

OE>>тестируй release, assert он только для разработчика, в debug-е
L>Не обязательно release, можно просто для найттестов брать билд в котором ассёрты не показывают окошко, а пишут проблему в лог.
L>В целом я о том что, Ассерт != окошко.

Во-во, понаставили граблей, повтыкали таблички: "Не ходить"
... << RSDN@Home 1.2.0 alpha 4 rev. 1048>>
Help will always be given at Hogwarts to those who ask for it.
Re[5]: опять про assert-ы
От: _FRED_ Черногория
Дата: 03.04.08 21:18
Оценка:
Здравствуйте, Odi$$ey, Вы писали:

OE>>>тестируй release, assert он только для разработчика, в debug-е

S>>А смысл тогда в таких ассертах, если они в тестах будут отключены? Если мой код использует библиотеку криво, я _всегда_ должен получать ошибку — и в дебаге и релизе.

OE>смысл assert-a — "визуализация" и контроль в процессе разработки неких условий, на которые полагается код. Если у тебя функция принимает int ты же не пытаешься тестировать ее заталкивая ей DateTime, string и дальше по списку. Точно также, если на входе функции стоит assert(i != 0) _бессмысленно_ "тестировать" ее передавая ей 0, получать кучу модальных окон и переживать по этому поводу. Срабатываний assert-ов вообще не должно быть, в отличии от результатов проверок входных параметров и еще чего-бы то ни было в runtime.


OE>Обнаружение неправильных параметров в процессе работы — нормальная ситуация, обнаружили — ура, тест прошел, программа работает. Если сработал assert — все, можно сливать воду, программа уже принципиально работает неправильно.


Ну так вот объясни мне где-нибудь разнгицу между асертом и исключением в твоём понимании?
... << RSDN@Home 1.2.0 alpha 4 rev. 1048>>
Help will always be given at Hogwarts to those who ask for it.
Re[6]: опять про assert-ы
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 04.04.08 04:20
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Ну так вот объясни мне где-нибудь разнгицу между асертом и исключением в твоём понимании?


вопрос поставлен некорректно, Исключения — это способ сигнализировать об ошибках при выполнении программы, с чем их можно сравнить, так это с return-ом кода ошибки. Assert — способ документировать логику которая программист зашивает в программу — на данный момент, в данной программе, в эту функцию не может быть передан 0 в качестве параметра. Чтоб не забыть это самому и не забыл никто я вставляю в начале Assert(i!=0). Можно отказаться от assert-ов и поголовно в каждой функции проверять проверять все параметры на допустимость и возвращать ошибку или кидать исключение если они некорректны. Но на практике, если я один раз проверил строку введенную пользователем и дальше она путешествует как const по десятку функций — нафига я в каждой функции при выполнении программы буду тратить время на проверку этого формата снова и снова? Лучше я впишу assert который явно обозначит, на что я полагался, когда писал эту функцию, все равно справку читать никто не будет, пока не получит линейкой по пальцам. Assert кстати может и не выводить окно с сообщением, а кидать исключение или писать в лог.

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

Если тебе непременно нужно обоснование именно такого понимания assert-ов, вот пара цитат из http://rsdn.ru/res/book/prog/codecomplete.xml:
Автор(ы): Стив Макконнелл

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


По мере возможности делайте интерфейсы программными, а не семантическими. Каждый интерфейс состоит из программной и семантической частей. Первая включает типы данных и другие атрибуты интерфейса, которые могут быть проверены компилятором. Вторая складывается из предположений об использовании интерфейса, которые компилятор проверить не может. Семантический интерфейс может включать такие соображения, как «Метод А должен быть вызван перед Методом В» или «Метод А вызовет ошибку, если переданный в него Элемент Данных 1 не будет перед этим инициализирован». Семантический интерфейс следует документировать в комментариях, но вообще интерфейсы должны как можно меньше зависеть от документации. Любой аспект интерфейса, который не может быть проверен компилятором, является потенциальным источником ошибок. Старайтесь преобразовывать семантические элементы интерфейса в программные, используя утверждения (assertions) или иными способами.


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

... << RSDN@Home 1.2.0 alpha 4 rev. 1061>>
Re[7]: опять про assert-ы
От: _FRED_ Черногория
Дата: 04.04.08 04:53
Оценка:
Здравствуйте, Odi$$ey, Вы писали:

_FR>>Ну так вот объясни мне где-нибудь разнгицу между асертом и исключением в твоём понимании?


OE>вопрос поставлен некорректно,


Почему? Посмотри на фреймворк. На другие, известные тебе и используемые тобой, .нет-библиотеки. Каким из двух способов они "документирует логику"? Есть ли хоть одна библиотека, в которой логика, как ты описываешь, регулируется именно асертами? Одна, конечно, может и найдётся (и всё же интересно, какая именно), но, уверен, это будет редким исключением.

OE>Исключения — это способ сигнализировать об ошибках при выполнении программы, с чем их можно сравнить, так это с return-ом кода ошибки. Assert — способ документировать логику которая программист зашивает в программу — на данный момент, в данной программе, в эту функцию не может быть передан 0 в качестве параметра.


Так "не может" или "не должен"? Выполнение асерта зависит от вызывающего или вызываемого кода (вызывающий, заметь, может быть написан совершенно не знакомым тебе человеком). С "не может" я как раз и согласен. Но в том разе, что _все_ исходы контролируются автором библиотеки\класса, а если выполнение условия зависит, например, о того, что сделано "с наружи" — мне не нравится. Пример:
public class MyClass
{
  public void Initialize() {
    // Как правильно:
    Debug.Assert(!IsInitialized, "!IsInitialized");
    // или
    if(IsInitialized) {
      throw new InvalidOperationException();
    }//if
    // вариант позволить несколько раз метод не рассматриваем :о)
    
    // ...
    IsInitialized = true;
  }
  
  private bool IsInitialized { 
    get; 
    set; 
  }
  
  public object GetData() {
    // Как правильно:
    Debug.Assert(IsInitialized, "!IsInitialized");
    // или
    if(!IsInitialized) {
      throw new InvalidOperationException();
    }//if

    //...
  }
}

?

OE>Чтоб не забыть это самому и не забыл никто я вставляю в начале Assert(i!=0).


Вот давай этот пример и рассмотрим. Я пишу библиотеку и у меня в ней есть некая функция, принимающая инт, но в которую нельзя передовать отрицательно число. Если поставлю асерт на это условие, то пользователям моей библиотеки это ни как не поможет: о них попросту не будет дебажной версии!

Описанный тобой подход работал в С++, где широко, если не почти повсемесно, библиотеки (если не учитывать open source) распространяются в нескольких версиях (debug, release, single-threaded, multi-threaded). И среда (MSVS) об этом знает и на это расчитана. В тех же ситeациях, когда пользователи библиотеки имеют один банарник (для не-С++-проектов, если ты заметил, "запросто" не сделать так, что бы при дебаге использовалась одна библиотека, по одному пути, а в релизе — другая) описанный тобой способ не принесёт ни какой пользы: информировать пользователя библиотеки о том, что библиотека не правильно используются можно только документацией и исключениями.

Какая тогда польза от асертов, которые проверяют пре\пост кондюшены?

OE>Если тебе непременно нужно обоснование именно такого понимания assert-ов, вот пара цитат из http://rsdn.ru/res/book/prog/codecomplete.xml:
Автор(ы): Стив Макконнелл

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


Спасибо, почитаю, потом прокоментирую.
... << RSDN@Home 1.2.0 alpha 4 rev. 1048>>
Help will always be given at Hogwarts to those who ask for it.
Re[8]: опять про assert-ы
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 04.04.08 05:13
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>>>Ну так вот объясни мне где-нибудь разнгицу между асертом и исключением в твоём понимании?

OE>>вопрос поставлен некорректно,

_FR>Почему?


разные вещи, разного назначения — какой смысл сравнивать расческу и зубную щетку

_FR>Посмотри на фреймворк. На другие, известные тебе и используемые тобой, .нет-библиотеки. Каким из двух способов они "документирует логику"? Есть ли хоть одна библиотека, в которой логика, как ты описываешь, регулируется именно асертами? Одна, конечно, может и найдётся (и всё же интересно, какая именно), но, уверен, это будет редким исключением.


.NET библиотеки большей частью распостраняются в бинарниках, поэтому навскидку у меня такого примера нет, попадется, покажу

_FR> // Как правильно:

_FR> Debug.Assert(!IsInitialized, "!IsInitialized");
_FR> // или
_FR> if(IsInitialized) {
_FR> throw new InvalidOperationException();

это не вопрос разницы Assert-ов и исключений, вместо throw new InvalidOperationException(); без всякого изменения смысла могло быть SetLastError(666); return false; Это вопрос — проверять ли в runtime всегда всё и вся или где-то можно полагаться на логику программы?

OE>>Чтоб не забыть это самому и не забыл никто я вставляю в начале Assert(i!=0).


_FR>Вот давай этот пример и рассмотрим. Я пишу библиотеку и у меня в ней есть некая функция, принимающая инт, но в которую нельзя передовать отрицательно число. Если поставлю асерт на это условие, то пользователям моей библиотеки это ни как не поможет: о них попросту не будет дебажной версии!


в релизе пользы от Assert-ов никакой, это аксиома
... << RSDN@Home 1.2.0 alpha 4 rev. 1061>>
Re[4]: опять про assert-ы
От: Mamut Швеция http://dmitriid.com
Дата: 04.04.08 07:00
Оценка: +1
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, Mamut, Вы писали:


_FR>>>Ну не принято почему-то у С++ — ников проверять аргументы при вызове (кстати, почему? банальная лень? экономия тактов на сравнениях?), а тут, в .NET, принято и этим надо пользоваться.


M>>Агресивное vs. защитное (agressive vs. defensive) программирование. В агрессивном вызывающая функция должна заботиться о правильности передаваемых параметров, а вызываемая — вылетать нафиг при первом же неудобном случае


_FR>Спасибо, поищу.


Я на самом деле это впервые увидел в правилах кодирования на Эрланге

M>>Иначе никаких if-ов и try-catch-ев не напасешься


_FR>Хм: в дотнете прекрасно напасаются


Ну, ото всех не спасешься Общая идея такая:
(тут я полез искать по РСДН, помнил, что это уже писал и наткнлся на ответ в ветке Философия Asserta
Автор: Mamut
Дата: 06.12.05
)

3.13 Не программируйте в "защитном" стиле

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

3.13 Do not program "defensively"

A defensive program is one where the programmer does not "trust" the input data to the part of the system they are programming. In general one should not test input data to functions for correctness. Most of the code in the system should be written with the assumption that the input data to the function in question is correct. Only a small part of the code should actually perform any checking of the data. This is usually done when data "enters" the system for the first time, once data has been checked as it enters the system it should thereafter be assumed correct.



То есть автор библиотеки прав, когда он не проверяет входящие данные на правильность, потому что ни уже должны быть правильными
... << RSDN@Home 1.2.0 alpha 4 rev. 1064>>


dmitriid.comGitHubLinkedIn
Re[4]: опять про assert-ы
От: minorlogic Украина  
Дата: 04.04.08 07:05
Оценка: 17 (3) +2
Здравствуйте, _FRED_, Вы писали:

_FR>Почитал, но ни где не нашёл твоих объяснений своей позиции Только "должно быть так и так", но не почему. В первую очередь мне любопытно: где разница между асертом и исключением?


Асерт это ошибка програмиста , исключение это ошибка программы.
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[8]: опять про assert-ы
От: andy1618 Россия  
Дата: 04.04.08 07:47
Оценка:
__>тут проблема в другом. как правило, assert проверяет целостность данных. если он не прошёл, то программа, как правило, не жилец в любом случае.
__>возможности корректного восстановления, как правило, нет.

Ну почему же — если в программе присутствует модульность, то уместна аналогия с отсеками подводной лодки: если в одном отсеке пробоина, то его задраивают и плывут потихоньку дальше. В реальности я это видел в ACDSee — когда какой-то плагин обкакался, основная программа спросила, что делать — пытаться работать дальше, или отрубить этот плагин нафиг. Весьма мудрое, на мой взгляд, поведение.
Re[9]: опять про assert-ы
От: Left2 Украина  
Дата: 04.04.08 08:03
Оценка:
A>Ну почему же — если в программе присутствует модульность, то уместна аналогия с отсеками подводной лодки: если в одном отсеке пробоина, то его задраивают и плывут потихоньку дальше. В реальности я это видел в ACDSee — когда какой-то плагин обкакался, основная программа спросила, что делать — пытаться работать дальше, или отрубить этот плагин нафиг. Весьма мудрое, на мой взгляд, поведение.

Проблема в том что по большому счёту для реализации такого поведения нужно либо писАть на managed языке, либо делать плагины отдельными процессами. Иначе ничто не помешает плагину "расстрелять" память основного процесса, после чего приложение будет вести себя абсолютно непредсказуемым образом.
... << RSDN@Home 1.2.0 alpha rev. 717>>
Re[6]: опять про assert-ы
От: TK Лес кывт.рф
Дата: 05.04.08 09:15
Оценка:
Здравствуйте, Severn, Вы писали:

S>Читай плз внимательнее о чем речь шла. При юнит тесте метода вылетит ассерт, если ассерт покажет UI сообщение, то протестировать метод не получится.


Вы, блин, как маленькие. Это все кастомизируется. Показывать UI сообщение в юнит тесте никто не заставляет — можно просто кинуть исключение или завершить текущий юнит тест еще каким способом
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[5]: опять про assert-ы
От: _FRED_ Черногория
Дата: 08.04.08 08:28
Оценка:
Здравствуйте, minorlogic, Вы писали:

_FR>>Почитал, но ни где не нашёл твоих объяснений своей позиции Только "должно быть так и так", но не почему. В первую очередь мне любопытно: где разница между асертом и исключением?


M>Асерт это ошибка програмиста , исключение это ошибка программы.


Ошибка того, кто написал асерт или того, кто вызвал функцию, в которой асерт произошёл? Именно это мне и интересно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1048>>
Help will always be given at Hogwarts to those who ask for it.
Re[5]: опять про assert-ы
От: _FRED_ Черногория
Дата: 08.04.08 09:14
Оценка:
Здравствуйте, Mamut, Вы писали:

M>3.13 Не программируйте в "защитном" стиле


Ужас. А если я всё-таки ошибся и начал передовать в некую библиотеку не правильные данные: представляешь себе, во что обойдётся поиск ошибки в подобной системе? Ведь с таким подходом теряет какой-либо смысл понятие "инварианта" (при условии, что все проверки построены на асертах и в релизе, который имеют пользователи библиотеки они не срабатывают).

Если с библиотекой обращаются не правильно (снабжают недопустимыми данными), она обязана выбросить исключение. Могу допустить, что ритм в этом деле должна задавать стандартная библиотека. Я не могу припомнить во фреймворке (.нет) класс, который вёл бы себя в "защищённом" стиле (если не считать очевидных ошибок в самом фреймворке). И это понятно почему: когда vs рассчитываем на то, что правильность вводимых данных контролирует вызывающий, то:
void Method(string input) {
  IntPtr handle = CreateSomeObject();
  WriteStringData(handle, input.Length, input);
  CloseHandle(handle);
}

как нечего делать ка нарваться на утечку, которую отыскать вызывающему будет очень не просто.

Я согласен с Framework Design Guidelines, которая говорит, что

Good framework design helps the application developer realize the benefits of exceptions.

... << RSDN@Home 1.2.0 alpha 4 rev. 1048>>
Help will always be given at Hogwarts to those who ask for it.
Re[6]: опять про assert-ы
От: Mamut Швеция http://dmitriid.com
Дата: 08.04.08 09:31
Оценка:
_FR>

M>>3.13 Не программируйте в "защитном" стиле


_FR>Ужас. А если я всё-таки ошибся и начал передовать в некую библиотеку не правильные данные: представляешь себе, во что обойдётся поиск ошибки в подобной системе?


Так не передавай

_FR> Ведь с таким подходом теряет какой-либо смысл понятие "инварианта" (при условии, что все проверки построены на асертах и в релизе, который имеют пользователи библиотеки они не срабатывают).


Ээээ. В смысле?

У тебя есть твоя функция f, которая вызывает библиотечную функцию bf. Если f передает в bf только правильные данные, то проблем не будет ни в дебаге ни в релизе

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


Зачем? В дебаге мы убеждаемся, что передаваемые в библиотеку данные правильные, переключаемся в релиз — и вперед

_FR>Я согласен с Framework Design Guidelines, которая говорит, что

_FR>

Good framework design helps the application developer realize the benefits of exceptions.


А я с этим категорически не согласен. Правильный гайдлайн должен быть таким:

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

... << RSDN@Home 1.2.0 alpha 4 rev. 1064>>


dmitriid.comGitHubLinkedIn
Re[7]: опять про assert-ы
От: _FRED_ Черногория
Дата: 08.04.08 11:14
Оценка:
Здравствуйте, Mamut, Вы писали:

_FR>>Ужас. А если я всё-таки ошибся и начал передовать в некую библиотеку не правильные данные: представляешь себе, во что обойдётся поиск ошибки в подобной системе?

M>Так не передавай

Сказать так намного проще, чем заставить несколько десятков человек "делать правильно, так, как нужно".

_FR>> Ведь с таким подходом теряет какой-либо смысл понятие "инварианта" (при условии, что все проверки построены на асертах и в релизе, который имеют пользователи библиотеки они не срабатывают).


M>Ээээ. В смысле?


M>У тебя есть твоя функция f, которая вызывает библиотечную функцию bf. Если f передает в bf только правильные данные, то проблем не будет ни в дебаге ни в релизе


Если bf (пусть это метод класса) не проверяет переданные ей аргументы, считая априори их верными, и пересчитывает на их основании данные класса, то данные класса зависят от того, как вызывать метод. В такой ситуации нельзя гарантировать, что данные класса находятся в согласованном состоянии.

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

M>Зачем? В дебаге мы убеждаемся, что передаваемые в библиотеку данные правильные, переключаемся в релиз — и вперед

Ага, у тебя есть дебажные версии сборок фреймворка, в которых будут срабатывать асерты? А даже если и есть (ой, писал я в этой ветке уже об этом: будто в чёрную дыру говорю ): ну нет в MSVS для .нет-проектов возможности (натуральной, не прикручиваемой сбоку) собирать дебаг моего проекта с дебажными сборками third party, а релиз — с релизными. Я вот сам лично не видел ни одного ассерта от стороннох библиотек, и,судя по сообщениям на форумах, этого не случается ни у кого, видимо потому, что так никто не работает.

_FR>>Я согласен с Framework Design Guidelines, которая говорит, что

_FR>>

Good framework design helps the application developer realize the benefits of exceptions.


M>А я с этим категорически не согласен. Правильный гайдлайн должен быть таким:

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


Ага, но "думать головой" — более абстрактное требование, которое моджно трактовать так, как захочется. И мы тут говорим не о починке данных. Говорим о диагностике, о сообщении о том, что произошло. При чём тут "починка"?
... << RSDN@Home 1.2.0 alpha 4 rev. 1048>>
Help will always be given at Hogwarts to those who ask for it.
Re[8]: опять про assert-ы
От: Mamut Швеция http://dmitriid.com
Дата: 08.04.08 11:48
Оценка:
_FR>>>Ужас. А если я всё-таки ошибся и начал передовать в некую библиотеку не правильные данные: представляешь себе, во что обойдётся поиск ошибки в подобной системе?
M>>Так не передавай

_FR>Сказать так намного проще, чем заставить несколько десятков человек "делать правильно, так, как нужно".


Ну ведь можно же помечтать


_FR>>> Ведь с таким подходом теряет какой-либо смысл понятие "инварианта" (при условии, что все проверки построены на асертах и в релизе, который имеют пользователи библиотеки они не срабатывают).


M>>Ээээ. В смысле?


M>>У тебя есть твоя функция f, которая вызывает библиотечную функцию bf. Если f передает в bf только правильные данные, то проблем не будет ни в дебаге ни в релизе


_FR>Если bf (пусть это метод класса) не проверяет переданные ей аргументы, считая априори их верными, и пересчитывает на их основании данные класса, то данные класса зависят от того, как вызывать метод. В такой ситуации нельзя гарантировать, что данные класса находятся в согласованном состоянии.



Извращенцы


Вообще в целом, "defensive programming", как и "aggressive programing" просто надо применять там где нужно. Но так хоццы асолюта
... << RSDN@Home 1.2.0 alpha 4 rev. 1064>>


dmitriid.comGitHubLinkedIn
Re[9]: опять про assert-ы
От: _FRED_ Черногория
Дата: 08.04.08 12:25
Оценка: +1
Здравствуйте, Mamut, Вы писали:

_FR>>Сказать так намного проще, чем заставить несколько десятков человек "делать правильно, так, как нужно".

M>Ну ведь можно же помечтать

Ага, пока не столкнёшся с бездумно натыканными асертами, проверяющими совсем не то, что надо.

M>Вообще в целом, "defensive programming", как и "aggressive programing" просто надо применять там где нужно.


В подобном стиле о чём угодно можно рассуждать :о)

M>Но так хоццы асолюта


Я привык верить, что так не бывает. Не бывает "само по себе", придти к этому можно лишь осуществив вполне определённые шаги, сводящие возможность ошибки к минимому и точно диагностирующие саму ошибку и место её возникновения, но ни как не запрещающие её. Человек имеет право на ошибку, и лишать его это права не честно но можно подсказать, где он не прав, или же помочь избежать ошибки.
... << RSDN@Home 1.2.0 alpha 4 rev. 1048>>
Help will always be given at Hogwarts to those who ask for it.
Re[6]: опять про assert-ы
От: minorlogic Украина  
Дата: 08.04.08 16:07
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, minorlogic, Вы писали:


_FR>>>Почитал, но ни где не нашёл твоих объяснений своей позиции Только "должно быть так и так", но не почему. В первую очередь мне любопытно: где разница между асертом и исключением?


M>>Асерт это ошибка програмиста , исключение это ошибка программы.


_FR>Ошибка того, кто написал асерт или того, кто вызвал функцию, в которой асерт произошёл? Именно это мне и интересно.


Чтобы ответить на этот вопрос необходимо рассмотреть конкретный пример.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[7]: опять про assert-ы
От: _FRED_ Черногория
Дата: 08.04.08 16:19
Оценка:
Здравствуйте, minorlogic, Вы писали:

>>>Асерт это ошибка програмиста , исключение это ошибка программы.

_FR>>Ошибка того, кто написал асерт или того, кто вызвал функцию, в которой асерт произошёл? Именно это мне и интересно.
M>Чтобы ответить на этот вопрос необходимо рассмотреть конкретный пример.

Выбирай любой:
int Method1(int index) {
  Debug.Assert(index >= 0, "index >= 0");
  return array[index];
}

void Method2() {
  Debug.Assert(!Thread.CurrentThread.IsBackground, "Should be called only from UI thread!");
  Application.Idle += delegate { };
}

void AddRef() {
  referencesCount++;
}

void Release() {
  Debug.Assert(referencesCount > 0, "No references!");
  referencesCount--;
}

void Dispose() {
  Debug.Assert(referencesCount == 0, "Reference leak!");
}
... << RSDN@Home 1.2.0 alpha 4 rev. 1048>>
Help will always be given at Hogwarts to those who ask for it.
Re[8]: опять про assert-ы
От: minorlogic Украина  
Дата: 08.04.08 17:20
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, minorlogic, Вы писали:


>>>>Асерт это ошибка програмиста , исключение это ошибка программы.

_FR>>>Ошибка того, кто написал асерт или того, кто вызвал функцию, в которой асерт произошёл? Именно это мне и интересно.
M>>Чтобы ответить на этот вопрос необходимо рассмотреть конкретный пример.

_FR>Выбирай любой:

_FR>
_FR>int Method1(int index) {
_FR>  Debug.Assert(index >= 0, "index >= 0");
_FR>  return array[index];
_FR>}
_FR>


Если код на шарпе то смысла большого не имеет . По любому будет сгенерированно исключение.
Если такое же на плюсах , то во первых можно unsigned использовать , а во вторых , таки да. Лишняя проверка может тормозить и лучше поставить ассерт на входных параметрах.


_FR>
_FR>void Method2() {
_FR>  Debug.Assert(!Thread.CurrentThread.IsBackground, "Should be called only from UI thread!");
_FR>  Application.Idle += delegate { };
_FR>}
_FR>

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


_FR>
_FR>void AddRef() {
_FR>  referencesCount++;
_FR>}

_FR>void Release() {
_FR>  Debug.Assert(referencesCount > 0, "No references!");
_FR>  referencesCount--;
_FR>}

_FR>void Dispose() {
_FR>  Debug.Assert(referencesCount == 0, "Reference leak!");
_FR>}
_FR>


Да, применение асерта проверяет правильность программы а не данных внутри нее. Таки образом мы проверяем наши внутрениие инварианты класса. Стоит ли использовать "Debug.Assert" или завести свою функциональность , к сожалению не могу сказать. Сильно специфично от библиотек.


Кстати использование асерта на шарпе уже не кажется столь прозрачным как на плюсах , это связанно со спецификой языка.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[10]: опять про assert-ы
От: minorlogic Украина  
Дата: 08.04.08 17:33
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Ага, пока не столкнёшся с бездумно натыканными асертами, проверяющими совсем не то, что надо.


Если даже асерты бездумно натыканы , то код ТОЧНО необходимо переписывать
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[9]: опять про assert-ы
От: _FRED_ Черногория
Дата: 08.04.08 18:35
Оценка:
Здравствуйте, minorlogic, Вы писали:

M>>>Чтобы ответить на этот вопрос необходимо рассмотреть конкретный пример.

_FR>>Выбирай любой:
_FR>>int Method1(int index) {
_FR>>  Debug.Assert(index >= 0, "index >= 0");
_FR>>  return array[index];
_FR>>}


M>Если код на шарпе то смысла большого не имеет . По любому будет сгенерированно исключение.

M>Если такое же на плюсах , то во первых можно unsigned использовать , а во вторых , таки да. Лишняя проверка может тормозить и лучше поставить ассерт на входных параметрах.

Это ты не знаешь Framework Design Guidelines: библиотека не должна выдавать "наружу" некоторые исключения:

Do not create methods that throw NullReferenceException or IndexOutOfRangeException.

(здесь)
. Например, стандартные библиотеки так не делают. Смысл в своей библиотеке делать иначе?

_FR>>void Method2() {
_FR>>  Debug.Assert(!Thread.CurrentThread.IsBackground, "Should be called only from UI thread!");
_FR>>  Application.Idle += delegate { };
_FR>>}

M>В данном случае ассерт оправдан. Во превых если метод вызван из другого потока то это ошибка не программы а програмиста.

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

M>Во вторых другого способа обеспечить этот контракт вероятно можно не найти.


А теперь представь себе, что будет в релизе: попросту не будет того, что нужно: у пользователя библиотеки может не быть исходного кода и отладочной версии. И, между прочим, почему бы тут не сделать проверку с исключением? Что бы на if-е съэкономить? Вот уж ни за что не поверю, что это место, требущее оптимизаций.

_FR>>void AddRef() {
_FR>>  referencesCount++;
_FR>>}

_FR>>void Release() {
_FR>>  Debug.Assert(referencesCount > 0, "No references!");
_FR>>  referencesCount--;
_FR>>}

_FR>>void Dispose() {
_FR>>  Debug.Assert(referencesCount == 0, "Reference leak!");
_FR>>}


M>Да, применение асерта проверяет правильность программы а не данных внутри нее.


Не понял: программа — это данные и операции над ними. Как можно проверить правильность операции не проверяя данные?

Вот, кстати, отыскал одной С++-ной библиотеке (comutil.h из поставки 2008ой студии):
inline BSTR _bstr_t::Detach()
{
    _COM_ASSERT(m_Data != NULL && m_Data->RefCount() == 1);

    if (m_Data != NULL && m_Data->RefCount() == 1) {
        BSTR b = m_Data->GetWString();
        m_Data->GetWString() = NULL;
        _Free();
        return b;
    } 
    else {
        _com_issue_error(E_POINTER);        
    }
}


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

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

M>Таки образом мы проверяем наши внутрениие инварианты класса.


Разве инвариант — это не данные?

M>Стоит ли использовать "Debug.Assert" или завести свою функциональность , к сожалению не могу сказать. Сильно специфично от библиотек.


Назови хоть одну библиотеку для .нет, логика которой построена на асертах?

M>Кстати использование асерта на шарпе уже не кажется столь прозрачным как на плюсах , это связанно со спецификой языка.


В смысле?
... << RSDN@Home 1.2.0 alpha 4 rev. 1048>>
Help will always be given at Hogwarts to those who ask for it.
Re[10]: опять про assert-ы
От: minorlogic Украина  
Дата: 09.04.08 05:27
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, minorlogic, Вы писали:


Выдавать или нет наружу
NullReferenceException or IndexOutOfRangeException
Не могу оценить . Но вижу причин этого не делать.


_FR>А теперь представь себе, что будет в релизе: попросту не будет того, что нужно: у пользователя библиотеки может не быть исходного кода и отладочной версии. И, между прочим, почему бы тут не сделать проверку с исключением? Что бы на if-е съэкономить? Вот уж ни за что не поверю, что это место, требущее оптимизаций.


Мотивация не делать проверку а использовать ассерт на входные данные может быть изза производительности . Для шарпа это редко бывает решающим фактором. Очевидно что необходимо проверять ВСЕ данные которые приходят извне в библиотеку.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[11]: опять про assert-ы
От: Cadet  
Дата: 10.04.08 15:52
Оценка: 1 (1) +1
Здравствуйте, minorlogic, Вы писали:

M>Выдавать или нет наружу

M>NullReferenceException or IndexOutOfRangeException
M>Не могу оценить . Но вижу причин этого не делать.

Отдавать надо ArgumentNullException, либо ArgumentOutOfRangeException. NullReferenceException или IndexOutOfRangeException — это значит разработчик библиотеки пустил неправильные параметры внутрь. NullReferenceException мне ничего не скажет. ArgumentNullException мне скажет о том, что такой-то параметр не может быть null. Аналогично и с *OutOfRangeException.
... << RSDN@Home 1.2.0 alpha 4 rev. 1074>>
Re[6]: опять про assert-ы
От: Юрий Жмеренецкий ICQ 380412032
Дата: 11.04.08 06:22
Оценка:
Здравствуйте, _FRED_, Вы писали:

M>>Асерт это ошибка програмиста , исключение это ошибка программы.


_FR>Ошибка того, кто написал асерт или того, кто вызвал функцию, в которой асерт произошёл? Именно это мне и интересно.


Если нарушены предусловия — виноват вызывающий,
если постусловия — виновата реализация, так как она не смогла выполнить свои обязанности(хотя клиент выполнил свои).
Re[7]: опять про assert-ы
От: _FRED_ Черногория
Дата: 12.04.08 18:12
Оценка: 1 (1)
Здравствуйте, Юрий Жмеренецкий, Вы писали:

M>>>Асерт это ошибка програмиста , исключение это ошибка программы.

_FR>>Ошибка того, кто написал асерт или того, кто вызвал функцию, в которой асерт произошёл? Именно это мне и интересно.
ЮЖ>Если нарушены предусловия — виноват вызывающий,

Конечно, виноват при нарушении предусловий вызывающий. Но почему проверять это нужно асертом, а не бросать исключение?
... << RSDN@Home 1.2.0 alpha 4 rev. 1048>>
Help will always be given at Hogwarts to those who ask for it.
Re[8]: опять про assert-ы
От: Юрий Жмеренецкий ICQ 380412032
Дата: 13.04.08 13:16
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, Юрий Жмеренецкий, Вы писали:


M>>>>Асерт это ошибка програмиста , исключение это ошибка программы.

_FR>>>Ошибка того, кто написал асерт или того, кто вызвал функцию, в которой асерт произошёл? Именно это мне и интересно.
ЮЖ>>Если нарушены предусловия — виноват вызывающий,

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


Если виноват — должен исправить(проверить явно). Иначе это не предусловие. здесь
Автор: Юрий Жмеренецкий
Дата: 12.04.08
более детально ответил.
Re: опять про assert-ы
От: remark Россия http://www.1024cores.net/
Дата: 13.04.08 22:34
Оценка: +1
Здравствуйте, Odi$$ey, Вы писали:

OE>Здравствуйте, _FRED_, Вы писали:


_FR>> пользователь моих биллиотек, для которого ассерт в _моём_ коде — означает (и правильно!) _мою_ ошибку,


OE>почему правильно-то? всю жизнь, и правильно, assert в коде библиотеки означал, что ее неправильно используют, не так как задумал автор



http://www.rsdn.ru/Forum/?mid=1874544
Автор: remark
Дата: 30.04.06




1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: опять про assert-ы
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 14.04.08 03:00
Оценка: +1
Здравствуйте, remark, Вы писали:

R>http://www.rsdn.ru/Forum/?mid=1874544
Автор: remark
Дата: 30.04.06


это:

>void my_assert(bool cond, const char* sz_cond, const char* func, const char* file, long line)
>{
>    if (IsDebuggerPresent())
>    {
>        __asm int 3
>    }
>    else
>    {
>        DebugWriteStack(sz_cond, func, file, line);
>        ShowErrorMessage(sz_cond, func, file, line);
>        throw MyAppLogicError(sz_cond, func, file, line);
>    }
>}
>
>#define ASSERT(cond) my_assert(cond, #cond, __FUNCTION__, __FILE__, __LINE__);

— зачем-то замаскированная под assert обычная проверка неких условий в runtime, в release и debug — конфигурациях. Я понимаю, что топик длинный и читать его лень, поэтому просто повторю то, что писал про этот вариант здесь
Автор: Odi$$ey
Дата: 04.04.08
— можно отказаться от assert-ов и поголовно в каждой функции проверять проверять все параметры или другие условия на допустимость и возвращать ошибку или кидать исключение если они некорректны. Но на практике, если я один раз проверил строку введенную пользователем и дальше она путешествует как const по десятку функций — нафига я в каждой функции при выполнении программы буду тратить время на проверку ее формата снова и снова? Лучше я впишу в них assert, который явно обозначит, на что я полагался, когда писал эти функции, при этом в release эта проверка не будет стоить мне ни одного лишнего такта.
... << RSDN@Home 1.2.0 alpha 4 rev. 1079>>
Re[9]: опять про assert-ы
От: _FRED_ Черногория
Дата: 14.04.08 05:15
Оценка:
Здравствуйте, Юрий Жмеренецкий, Вы писали:

M>>>>>Асерт это ошибка програмиста , исключение это ошибка программы.

_FR>>>>Ошибка того, кто написал асерт или того, кто вызвал функцию, в которой асерт произошёл? Именно это мне и интересно.
ЮЖ>>>Если нарушены предусловия — виноват вызывающий,

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


ЮЖ>Если виноват — должен исправить(проверить явно). Иначе это не предусловие.


Извини, но ты програмируешь на .NET? Часто нарывался на асерты в сторонних библиотеках? А на ArgumentNullException? Не задумывался, почему для проверки предусловий в стандартных библиотеках используются исключения вместо асертов?

ЮЖ>здесь
Автор: Юрий Жмеренецкий
Дата: 12.04.08
более детально ответил.


Ничего, если чесно, не понял
... << RSDN@Home 1 alpha 3 rev. 0>>
Help will always be given at Hogwarts to those who ask for it.
Re[10]: опять про assert-ы
От: Юрий Жмеренецкий ICQ 380412032
Дата: 14.04.08 06:02
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Извини, но ты програмируешь на .NET? Часто нарывался на асерты в сторонних библиотеках? А на ArgumentNullException? Не задумывался, почему для проверки предусловий в стандартных библиотеках используются исключения вместо асертов?


Предусловия по определению не нужно проверять(внутри функции).
Re[11]: опять про assert-ы
От: _FRED_ Черногория
Дата: 14.04.08 06:06
Оценка:
Здравствуйте, Юрий Жмеренецкий, Вы писали:

_FR>>Извини, но ты програмируешь на .NET?


Ы?

_FR>>Часто нарывался на асерты в сторонних библиотеках? А на ArgumentNullException? Не задумывался, почему для проверки предусловий в стандартных библиотеках используются исключения вместо асертов?


ЮЖ>Предусловия по определению не нужно проверять(внутри функции).


Чем же тогда объяснить наличие ArgumentException и наследников? Кривостью дизайна .NET Framework?
... << RSDN@Home 1 alpha 3 rev. 0>>
Help will always be given at Hogwarts to those who ask for it.
Re[12]: опять про assert-ы
От: Юрий Жмеренецкий ICQ 380412032
Дата: 14.04.08 07:48
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>>>Извини, но ты програмируешь на .NET?

В контексте топика это не имеет значения.

ЮЖ>>Предусловия по определению не нужно проверять(внутри функции).

_FR>Чем же тогда объяснить наличие ArgumentException и наследников? Кривостью дизайна .NET Framework?
Само наличие еще ни о чем не говорит. А вот использование.. Явная проверка предусловий(это, кстати факт того что предусловия попросту отсутствуют) в функции говорит о том что программа(здесь Framework) не использует design-by-contract(в принципе под определение подвести конечно можно, но это будет притягиванием за уши). Это просто другой подход. В чем-то лучше, в чем-то хуже... Основное отличие в том что если срабатывает assert то программу нужно исправлять, а не выкидывать исключения.
Re[13]: опять про assert-ы
От: _FRED_ Черногория
Дата: 14.04.08 07:56
Оценка:
Здравствуйте, Юрий Жмеренецкий, Вы писали:

_FR>>>>Извини, но ты програмируешь на .NET?

ЮЖ>В контексте топика это не имеет значения.

Ну тогда и говорить не о чем: представь себе библиотеку, которая об ошибках сообщает через асерты. Как с ней работать, имея только релизные сборки?
... << RSDN@Home 1 alpha 3 rev. 0>>
Help will always be given at Hogwarts to those who ask for it.
Re[14]: опять про assert-ы
От: Юрий Жмеренецкий ICQ 380412032
Дата: 14.04.08 08:47
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>>>>>Извини, но ты програмируешь на .NET?

ЮЖ>>В контексте топика это не имеет значения.

_FR>Ну тогда и говорить не о чем: представь себе библиотеку, которая об ошибках сообщает через асерты. Как с ней работать, имея только релизные сборки?


assert — это не способ обнаружения ошибок. Если есть предусловия, то они должны выполняться, если отсутствуют — то постусловия должны перечилслять все возможные ошибки(исключения). При использовании DbC проверки аргументов никуда не исчезают, они переносятся на уровень выше как предусловия. Чем "глубже" в библиотеку — тем меньше явных проверок, т.к. некоторые предусловия выполняются автоматически будучи уже проверенными(причем один раз) выше.
Re[15]: опять про assert-ы
От: _FRED_ Черногория
Дата: 14.04.08 08:57
Оценка:
Здравствуйте, Юрий Жмеренецкий, Вы писали:

_FR>>>>>>Извини, но ты програмируешь на .NET?

ЮЖ>>>В контексте топика это не имеет значения.
_FR>>Ну тогда и говорить не о чем: представь себе библиотеку, которая об ошибках сообщает через асерты. Как с ней работать, имея только релизные сборки?
ЮЖ>assert — это не способ обнаружения ошибок. Если есть предусловия, то они должны выполняться, если отсутствуют — то постусловия должны перечилслять все возможные ошибки(исключения).

Кто должен нести ответственность за соблюдение "предусловий" (если под предусловиями понимать значение передаваемых аргументов, как в рассматриваемом примере
Автор: _FRED_
Дата: 08.04.08
)? Вызывающий. Если мы проверяем предусловия асертом, а у вызывающего только релиз — как он об этом узнает?
  1. Получит исключения, как в правильном по моему мнению примере
  2. Программа глухо свёрнётся из-за ошибки доступа по невалидному адресу
  3. Программа будет как-то неправильно работать
Я предпочитаю исключения.
... << RSDN@Home 1 alpha 3 rev. 0>>
Help will always be given at Hogwarts to those who ask for it.
Re[10]: опять про assert-ы
От: Lloyd Россия  
Дата: 14.04.08 09:06
Оценка:
Здравствуйте, _FRED_, Вы писали:

ЮЖ>>Если виноват — должен исправить(проверить явно). Иначе это не предусловие.


_FR>Извини, но ты програмируешь на .NET? Часто нарывался на асерты в сторонних библиотеках? А на ArgumentNullException? Не задумывался, почему для проверки предусловий в стандартных библиотеках используются исключения вместо асертов?


Может быть потому что стандартные библиотеки скомпилированы не в дебаге, а в релизе?
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re[11]: опять про assert-ы
От: _FRED_ Черногория
Дата: 14.04.08 09:23
Оценка:
Здравствуйте, Lloyd, Вы писали:

ЮЖ>>>Если виноват — должен исправить(проверить явно). Иначе это не предусловие.


_FR>>Извини, но ты програмируешь на .NET? Часто нарывался на асерты в сторонних библиотеках? А на ArgumentNullException? Не задумывался, почему для проверки предусловий в стандартных библиотеках используются исключения вместо асертов?


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


Именно об этом я и говорю. В .NET ещё (или ужЕ) на уровне основной среды разработки (MSVS) не предусмотрено использование разных (конфигураций) сборок в зависимоти от конфигурации проекта, поэтому подавляющее большинство програмистов пишет и отлаживает свой код с релизом чужих сборок. Поэтому, чем более "умная" окажется чужая сборка, чем более удобные и понятные сообщения об ошибках из неё можно получить, чем более она соответствует принципам, изложенным здесь, тем удобнее в использовании она окажется для разработчиков-пользователей.

А для этого, нельзя полагаться на верность данных, получаемых "извне", от вызывающего кода и бессмысленно ставить асерты на условия, зависящие от вызывающего кода. Перенося обязанность проверки на вызывающий код, автор библиотеки усложняет жизнь вызывающему (который может использовать десяток-другой различных библиотек и будет обязан разобраться в тонкостях работы с каждой). хорошая библиотека (как и любой кусок хорошего кода) должен быть "готов к использованию", должен быть "кирпичём", из которого можно сложить необходимое, а не полуфабрикатом, который надо бережно и внимательно доготовить.

Прикладной програмист должен думать о своих задачах, и не удилять _излишне_ много времени изучению кода, который он вызывает, и это достижимо, когда вызываемый код понятно говорит о том, в чём проблема, а не ставит, например, перед фактом — "некая переменная по такому-то адресу оказась равной null".
... << RSDN@Home 1 alpha 3 rev. 0>>
Help will always be given at Hogwarts to those who ask for it.
Re[12]: опять про assert-ы
От: Lloyd Россия  
Дата: 14.04.08 09:26
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>>>Извини, но ты програмируешь на .NET? Часто нарывался на асерты в сторонних библиотеках? А на ArgumentNullException? Не задумывался, почему для проверки предусловий в стандартных библиотеках используются исключения вместо асертов?


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


_FR>Именно об этом я и говорю. В .NET ещё (или ужЕ) на уровне основной среды разработки (MSVS) не предусмотрено использование разных (конфигураций) сборок в зависимоти от конфигурации проекта, поэтому подавляющее большинство програмистов пишет и отлаживает свой код с релизом чужих сборок. Поэтому, чем более "умная" окажется чужая сборка, чем более удобные и понятные сообщения об ошибках из неё можно получить, чем более она соответствует принципам, изложенным здесь, тем удобнее в использовании она окажется для разработчиков-пользователей.


Но вы кажется обсуждаете использование ассертов как таковое, а не конкретно в .net. Поэтому не совсем понятно при чем тут отсутствие/наличие дебажных версий сборок в фреймворке.
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re[13]: опять про assert-ы
От: _FRED_ Черногория
Дата: 14.04.08 09:36
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Но вы кажется обсуждаете использование ассертов как таковое, а не конкретно в .net. Поэтому не совсем понятно при чем тут отсутствие/наличие дебажных версий сборок в фреймворке.


Нет, выше я уже говорил, что тут надо ориентироваться на стандартные библиотеки и на технологию.

Если же говорить вообще, то Саттер или Маерс где-то хорошо об этом сказали, но у меня нет сейчас доступа к своим книгам
... << RSDN@Home 1 alpha 3 rev. 0>>
Help will always be given at Hogwarts to those who ask for it.
Re[16]: опять про assert-ы
От: Юрий Жмеренецкий ICQ 380412032
Дата: 14.04.08 09:39
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Кто должен нести ответственность за соблюдение "предусловий" (если под предусловиями понимать значение передаваемых аргументов, как в рассматриваемом примере
Автор: _FRED_
Дата: 08.04.08
)? Вызывающий. Если мы проверяем предусловия асертом,

Да не проверяем мы предусловия ассертом.

_FR>а у вызывающего только релиз — как он об этом узнает?

Из контракта. Может выражаться разными способами:

//pre a > 0 Явно в документации 
void foo(int a);

//или так(что лучше)
void foo(positive_int a);

или еще как-нибудь...

_FR>

    _FR>
  1. Получит исключения, как в правильном по моему мнению примере
    _FR>
  2. Программа глухо свёрнётся из-за ошибки доступа по невалидному адресу
    _FR>
  3. Программа будет как-то неправильно работать
    _FR>
_FR>Я предпочитаю исключения.

Вот. Получается что вызывающий, в твоем случае, не выполнил контракт, но программа диагностировала это как "нормальную" ситуацию. Вот это я называю "замазыванием" ошибок. Для меня это значит что программа попросту некорректна и ее надо исправлять, т.к. произошло нарушение контракта. Повторюсь — "проверки аргументов никуда не исчезают, они переносятся на уровень выше". Утверждения, проверяемые assert'ами _всегда_ выполняются. Поэтому их можно выкидывать из релиза. В случае с positive_int(выше) assert теоретически вообще не нужен. т.к. контракт выражен статически(если для positive_int инвариантом является хранение положительного числа) и проверка что 'a>0' выполняется выше.
Re[16]: опять про assert-ы
От: minorlogic Украина  
Дата: 14.04.08 10:11
Оценка:
Тот способ которым ты пытаешься использовать assert не соответствует его пердназначению . Например проверять ассертом входные данные для отдельной БИБЛИОТЕКИ это моветон.

Хорошим стилем для интерфейса модуля является проверка входных данных и генерация исключения если данные невалидны.
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[17]: опять про assert-ы
От: _FRED_ Черногория
Дата: 14.04.08 10:16
Оценка: 1 (1) +1
Здравствуйте, minorlogic, Вы писали:

M>Тот способ которым ты пытаешься использовать assert не соответствует его пердназначению . Например проверять ассертом входные данные для отдельной БИБЛИОТЕКИ это моветон.


M>Хорошим стилем для интерфейса модуля является проверка входных данных и генерация исключения если данные невалидны.


Я, как раз то, считаю что асертом нужно проверять исключительно данные\состояния, на которые внешний, вызывающий код повлиять не может. Именно тогда асерт говорит о том, что _я_ нарушил один из _собственных_ инвариантов. И именно мой код (в котором выставлен асерт) нуждается в исправлении.
... << RSDN@Home 1 alpha 3 rev. 0>>
Help will always be given at Hogwarts to those who ask for it.
Re[18]: опять про assert-ы
От: minorlogic Украина  
Дата: 14.04.08 10:36
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Я, как раз то, считаю что асертом нужно проверять исключительно данные\состояния, на которые внешний, вызывающий код повлиять не может. Именно тогда асерт говорит о том, что _я_ нарушил один из _собственных_ инвариантов. И именно мой код (в котором выставлен асерт) нуждается в исправлении.


Тогда и спор у вас какойто странный , проверять ли библиотеке входные данные или нет. Конечно проверять! кто только об этом не писал .
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[12]: опять про assert-ы
От: Юрий Жмеренецкий ICQ 380412032
Дата: 14.04.08 10:58
Оценка:
Здравствуйте, _FRED_, Вы писали:

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


Как быть в случае необходимости локализации сообщений об ошибках?

_FR>А для этого, нельзя полагаться на верность данных, получаемых "извне", от вызывающего кода и бессмысленно ставить асерты на условия, зависящие от вызывающего кода. Перенося обязанность проверки на вызывающий код, автор библиотеки усложняет жизнь вызывающему (который может использовать десяток-другой различных библиотек и будет обязан разобраться в тонкостях работы с каждой).


Возникающие исключения — тоже тонкости работы.

Чем это:
try
{
  int a = get();
  foo(a);  // даже если get гарантирует что возвращенное значение > 0, то в foo все равно будет повторная проверка
}
catch(InvalidArgument)
{
 Message("error");
}

лучше чем это
int a = get()
if(a > 0) // А это можно убрать если get гарантирует что a>0
  foo(a);
else
 Message("error");


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


То есть "значения аргументов могут быть любыми(предусловия отсутствуют), попытаемся вызвать, вдруг чего получится"?
Для некоторых ситуаций, да, такой подход имеет смысл, но только тогда, когда результат проверки предусловий теряет актуальность после этой проверки. Вроде выделения памяти: Если у нас будет функция проверки объема доступной памяти, то результат ее вызова не имеет смысла, поскольку за время между ее вызовом и запросом на выделение кто-то другой может забрать весь объем доступный объем.
Re[18]: опять про assert-ы
От: Юрий Жмеренецкий ICQ 380412032
Дата: 14.04.08 11:02
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Я, как раз то, считаю что асертом нужно проверять исключительно данные\состояния, на которые внешний, вызывающий код повлиять не может. Именно тогда асерт говорит о том, что _я_ нарушил один из _собственных_ инвариантов. И именно мой код (в котором выставлен асерт) нуждается в исправлении.


Полностью согласен. Только это постусловия. Если мы не можем их выполнить, то нарушаем контракт и необходимо исправление. Только вот есть еще предусловия, за выполнение которых несет ответственность клиент.
Re[19]: опять про assert-ы
От: _FRED_ Черногория
Дата: 14.04.08 11:23
Оценка:
Здравствуйте, minorlogic, Вы писали:

_FR>>Я, как раз то, считаю что асертом нужно проверять исключительно данные\состояния, на которые внешний, вызывающий код повлиять не может. Именно тогда асерт говорит о том, что _я_ нарушил один из _собственных_ инвариантов. И именно мой код (в котором выставлен асерт) нуждается в исправлении.


M>Тогда и спор у вас какойто странный , проверять ли библиотеке входные данные или нет. Конечно проверять! кто только об этом не писал .


Началось всё с того, что я уточнил мнение TK:А на сколько это правильно: ставить ассерт?
Автор: _FRED_
Дата: 02.04.08
, который отшутился, а мы с Odi$$ey-ем стали разбираться, как же надо
Автор: Odi$$ey
Дата: 02.04.08
. Да, видать, только всех вокруг и сами себя запутали :о))

Дело там не только во входных данных, сколько от условий, зависящих от внешнего (по отношению к методу, классу, сборке, …) мира.
... << RSDN@Home 1 alpha 3 rev. 0>>
Help will always be given at Hogwarts to those who ask for it.
Re[13]: опять про assert-ы
От: anton_t Россия  
Дата: 14.04.08 11:30
Оценка:
Здравствуйте, Юрий Жмеренецкий, Вы писали:

ЮЖ>То есть "значения аргументов могут быть любыми(предусловия отсутствуют), попытаемся вызвать, вдруг чего получится"?


Мне вот что не понятно: каким образом генерация исключений в случае не выполнения предусловий мешает описанию этих предусловий в документации?
Re[14]: опять про assert-ы
От: Юрий Жмеренецкий ICQ 380412032
Дата: 14.04.08 12:47
Оценка:
Здравствуйте, anton_t, Вы писали:

ЮЖ>>То есть "значения аргументов могут быть любыми(предусловия отсутствуют), попытаемся вызвать, вдруг чего получится"?


_>Мне вот что не понятно: каким образом генерация исключений в случае не выполнения предусловий мешает описанию этих предусловий в документации?


"Генерация исключения X в случае выполнения condition(Y)" — Это постусловие. Предусловие выполняется всегда, поэтому оно и "предварительное условие". Можно сказать что любой код с 'if' проверяет некоторое предусловие.
Re[15]: опять про assert-ы
От: _FRED_ Черногория
Дата: 15.04.08 07:05
Оценка:
Здравствуйте, Юрий Жмеренецкий, Вы писали:

ЮЖ>>>То есть "значения аргументов могут быть любыми(предусловия отсутствуют), попытаемся вызвать, вдруг чего получится"?

_>>Мне вот что не понятно: каким образом генерация исключений в случае не выполнения предусловий мешает описанию этих предусловий в документации?
ЮЖ>"Генерация исключения X в случае выполнения condition(Y)" — Это постусловие.

Предусловие (выполнения метода) — это "condition", а не "Генерация исключения".
... << RSDN@Home 1 alpha 3 rev. 0>>
Help will always be given at Hogwarts to those who ask for it.
Re[17]: опять про assert-ы
От: Legion13  
Дата: 15.04.08 09:11
Оценка: 1 (1)
Здравствуйте, minorlogic, Вы писали:

M>Например проверять ассертом входные данные для отдельной БИБЛИОТЕКИ это моветон.

M>Хорошим стилем для интерфейса модуля является проверка входных данных и генерация исключения если данные невалидны.

Наверное, это уже где-то обсуждалось, но выскажу свое отношение к данному вопросу.
Для меня assert — дополнительная приятность при тестировании, основное назначение которой — сразу же перейти в отладчик по месту возникновения проблемы.
И обработка передаваемых методу аргументов примерно такая:

Debug.Assert(null != table, "null != table");
if (null == table)
    throw new ArgumentNullException("table");


То есть, на стадии тестирования при debug-версии библиотеки/приложения я буду работать с удобным окном assert, ну а в release-версии будут исключения, опять же по месту возникновения проблемы.
... << RSDN@Home 1.2.0 alpha rev. 717>>
Re[18]: опять про assert-ы
От: _FRED_ Черногория
Дата: 16.04.08 06:37
Оценка:
Здравствуйте, Legion13, Вы писали:

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

L>И обработка передаваемых методу аргументов примерно такая:
L>Debug.Assert(null != table, "null != table");
L>if (null == table)
L>    throw new ArgumentNullException("table");


Для этих целей предназначен совсем другой инструмент (в MSVS), а именно расстановка галок в колонке "Thrown" диалога Debug\Exceptions…

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

Теперь представь, что показанный тобой код расположен в библиотеке, которая является частью солюшена и другой разработчик вызывает код твоей библиотеке. С его точки зрения может быть вполне логичто но, что происходит исключение (он тожде не собирается его обрабатывать и будет передавать его дальше "на верх"). Но его код при отладке не сможет нормально работать, так как "некто" воткнул в него асерт, и вместо того, что бы работать, как положено при возникновении исключения, программа поведёт себя не так, как должна.

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

Асерт — это ошибка того, кто его поставил, а не того, кто на него наткнулся.
... << RSDN@Home 1 alpha 3 rev. 0>>
Help will always be given at Hogwarts to those who ask for it.
Re[19]: опять про assert-ы
От: remark Россия http://www.1024cores.net/
Дата: 16.04.08 07:07
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Теперь представь, что показанный тобой код расположен в библиотеке, которая является частью солюшена и другой разработчик вызывает код твоей библиотеке. С его точки зрения может быть вполне логичто но, что происходит исключение (он тожде не собирается его обрабатывать и будет передавать его дальше "на верх"). Но его код при отладке не сможет нормально работать, так как "некто" воткнул в него асерт, и вместо того, что бы работать, как положено при возникновении исключения, программа поведёт себя не так, как должна.



Почему же не так? Давишь в окошке "Продолжить" и смотришь как программа себя поведёт без ассёрта.



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[20]: опять про assert-ы
От: _FRED_ Черногория
Дата: 16.04.08 08:38
Оценка:
Здравствуйте, remark, Вы писали:

R>Почему же не так? Давишь в окошке "Продолжить" и смотришь как программа себя поведёт без ассёрта.


Хе-хе :о)) а если это, например, обработчик драг-дропа или что-то, что вызывается по сотне раз в секунду в цикле? В общем. не всегда желательно срабатывание асерта, а уж если произошло, то это должно быть нечто, что нужно немедленно исправлять, а не добавлять проверок.

R>

... << RSDN@Home 1 alpha 3 rev. 0>>
Help will always be given at Hogwarts to those who ask for it.
Re[21]: опять про assert-ы
От: Kluev  
Дата: 02.06.08 12:59
Оценка: 29 (2)
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, remark, Вы писали:


R>>Почему же не так? Давишь в окошке "Продолжить" и смотришь как программа себя поведёт без ассёрта.


_FR>Хе-хе :о)) а если это, например, обработчик драг-дропа или что-то, что вызывается по сотне раз в секунду в цикле?


Нужно просто использовать правильные ассерты.

Re[22]: опять про assert-ы
От: _FRED_ Черногория
Дата: 03.06.08 05:20
Оценка:
Здравствуйте, Kluev, Вы писали:

R>>>Почему же не так? Давишь в окошке "Продолжить" и смотришь как программа себя поведёт без ассёрта.

_FR>>Хе-хе :о)) а если это, например, обработчик драг-дропа или что-то, что вызывается по сотне раз в секунду в цикле?
K>Нужно просто использовать правильные ассерты.
K>http://files.rsdn.ru/16157/assert.png

Осталось научить сервис, стоящий на сервере "без окон и дверей" жать такую кнопку
А идея очень даже красивая, для некоторый случаев
... << RSDN@Home 1 alpha 3 rev. 0>>
Help will always be given at Hogwarts to those who ask for it.
Re[23]: опять про assert-ы
От: Kluev  
Дата: 03.06.08 09:24
Оценка: 1 (1) :)))
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, Kluev, Вы писали:


R>>>>Почему же не так? Давишь в окошке "Продолжить" и смотришь как программа себя поведёт без ассёрта.

_FR>>>Хе-хе :о)) а если это, например, обработчик драг-дропа или что-то, что вызывается по сотне раз в секунду в цикле?
K>>Нужно просто использовать правильные ассерты.
K>>http://files.rsdn.ru/16157/assert.png

_FR>Осталось научить сервис, стоящий на сервере "без окон и дверей" жать такую кнопку

Зачем же сразу катать квадратное и носить круглое? Каждой задаче — свой адекватный инструмент.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.