Сообщение Re[28]: {@Sinix} Да ну и фиг с этой Java-ой. .Net будет убит от 10.08.2016 14:59
Изменено 10.08.2016 16:44 Evgeny.Panasyuk
Здравствуйте, ·, Вы писали:
EP>>·>Тут не в сомнениях дело. А сам факт того, что если условие ассерта не сработает в релизе — то угадать что будет — невозможно.
EP>>assert'ы применяются намного шире чем простейший bounds checking — для проверки пред/пост-условий, для проверки инвариантов и вариантов циклов, для проверки инвариантов классов и т.п.
·>А что они дают-то? Почему вместо assert x просто нельзя if(!x) throw Boom()?
Почему нельзя? — Можно (есть конечно случаи где нужен именно no-throw код, иначе в процессе раскрутки поломаются другие инварианты, но это отдельная тема, не особо влияющая на суть данной дискуссии).
Отличительная черта assert'ов — в том что они могут быть опционально отключены, более того — для формально верифицированного кода они не нужны.
·>Если медленно — это уже проблема алгоритма.
Это ещё почему?
·>При хорошем покрытии тестами ценность ассертов падает до нуля.
Точно также как и ценность других defensive примочек, а-ля bounds checking
EP>>С другой стороны, выключение части из проверок в runtime'е, ровно как и отсутствии часть проверок вообще — не делает программу некорректной.
·>Но только если ассерты расставлены корректно.
Что ты имеешь в виду? То что проверка внутри assert'а может иметь side-effect?
EP>>>>ЕМНИП Sinix рассказывал что использует их во всю как раз в managed языке.
EP>>·>Можно, конечно. Но непонятно зачем. А где он об этом писал?
EP>>Много где, можем попробовать его призвать сюда. Например в CodeJam сделали компонент Assertions.
·>Я что-то не понял что это. Судя по if (!condition)throw это не ассерты в понимании С++.
Там некоторые из них опциональные, и не попадают в Release.
EP>>В целом не пойму почему ты проводишь разделение managed/не managed относительно assert'ов.
·>Это в ответ на то, что в С++ "включаются asserts, checked iterators и прочий defensive programming". Ассерты тут как частный случай скорее.
·>Т.е. в managed у тебя всегда работает правильно, а когда может — работает быстро.
Ты как-то перекручиваешь слова. Не "правильно", а ранее обнаружение бага, что вовсе не означает "правильно" — твой код уже пришёл в состояние в котором он быть не должен был, и неизвестно как он туда попал, и что уже натворил по пути.
·>В unmanaged наоборот: когда может — работает правильно, и всегда быстро.
Не всегда быстро, только когда assert'ы отключены.
EP>>·>Они позволяют избежать UB. Грубо говоря некий такой wysiwyg — как код написан, так он и исполняется. А не так, что вышли за границы массива или обратились к неинициализированной памяти — и последствия совершенно непредсказуемы.
EP>>Это лишь только для мизерной части утверждений корректности программы. Если ты не расписал все утверждения корректности, то никакого "WYSIWYG" — очевидно нет
·>Есть конечно. Я говорю о корректности самого кода, а не логических ошибок в алгоритме.
В чём ты видишь отличие? Выход за пределы bounds это есть логическая ошибка, которой в корректном коде нет
·>Т.е. в С++ если видишь, что у тебя в коде написано a = b + c то при известных значениях b==1 и c==2 может случиться, что a!=3 т.к. где-то что-то стрельнуло по памяти из другого треда. В managed — a==3 всегда, доказано верификатором.
Не доказано — ибо точно также используется не-managed код, точно также есть компилятор в котором могут быть баги, и даже железо может сбоить
EP>>P.S. Ничто не мешает оставить часть assert'ов включенных в Release. Для этого их обычно разбивают на классы "быстрые", "медленные", "очень медленные" — и уже пользователь библиотеки решает что попадёт в Release.
·>По-моему излишнее усложнение. Собственно на основании чего пользователь будет принимать решение?
1. На основании того какое быстродействие его устраивает
2. На основании того насколько корректен его код (здесь речь идёт про библиотеку и пользовательский код, ассерты внутри библиотеки могут ловить ошибки в пользовательском коде).
EP>>·>Тут не в сомнениях дело. А сам факт того, что если условие ассерта не сработает в релизе — то угадать что будет — невозможно.
EP>>assert'ы применяются намного шире чем простейший bounds checking — для проверки пред/пост-условий, для проверки инвариантов и вариантов циклов, для проверки инвариантов классов и т.п.
·>А что они дают-то? Почему вместо assert x просто нельзя if(!x) throw Boom()?
Почему нельзя? — Можно (есть конечно случаи где нужен именно no-throw код, иначе в процессе раскрутки поломаются другие инварианты, но это отдельная тема, не особо влияющая на суть данной дискуссии).
Отличительная черта assert'ов — в том что они могут быть опционально отключены, более того — для формально верифицированного кода они не нужны.
·>Если медленно — это уже проблема алгоритма.
Это ещё почему?
·>При хорошем покрытии тестами ценность ассертов падает до нуля.
Точно также как и ценность других defensive примочек, а-ля bounds checking
EP>>С другой стороны, выключение части из проверок в runtime'е, ровно как и отсутствии часть проверок вообще — не делает программу некорректной.
·>Но только если ассерты расставлены корректно.
Что ты имеешь в виду? То что проверка внутри assert'а может иметь side-effect?
EP>>>>ЕМНИП Sinix рассказывал что использует их во всю как раз в managed языке.
EP>>·>Можно, конечно. Но непонятно зачем. А где он об этом писал?
EP>>Много где, можем попробовать его призвать сюда. Например в CodeJam сделали компонент Assertions.
·>Я что-то не понял что это. Судя по if (!condition)throw это не ассерты в понимании С++.
Там некоторые из них опциональные, и не попадают в Release.
EP>>В целом не пойму почему ты проводишь разделение managed/не managed относительно assert'ов.
·>Это в ответ на то, что в С++ "включаются asserts, checked iterators и прочий defensive programming". Ассерты тут как частный случай скорее.
·>Т.е. в managed у тебя всегда работает правильно, а когда может — работает быстро.
Ты как-то перекручиваешь слова. Не "правильно", а ранее обнаружение бага, что вовсе не означает "правильно" — твой код уже пришёл в состояние в котором он быть не должен был, и неизвестно как он туда попал, и что уже натворил по пути.
·>В unmanaged наоборот: когда может — работает правильно, и всегда быстро.
Не всегда быстро, только когда assert'ы отключены.
EP>>·>Они позволяют избежать UB. Грубо говоря некий такой wysiwyg — как код написан, так он и исполняется. А не так, что вышли за границы массива или обратились к неинициализированной памяти — и последствия совершенно непредсказуемы.
EP>>Это лишь только для мизерной части утверждений корректности программы. Если ты не расписал все утверждения корректности, то никакого "WYSIWYG" — очевидно нет
·>Есть конечно. Я говорю о корректности самого кода, а не логических ошибок в алгоритме.
В чём ты видишь отличие? Выход за пределы bounds это есть логическая ошибка, которой в корректном коде нет
·>Т.е. в С++ если видишь, что у тебя в коде написано a = b + c то при известных значениях b==1 и c==2 может случиться, что a!=3 т.к. где-то что-то стрельнуло по памяти из другого треда. В managed — a==3 всегда, доказано верификатором.
Не доказано — ибо точно также используется не-managed код, точно также есть компилятор в котором могут быть баги, и даже железо может сбоить
EP>>P.S. Ничто не мешает оставить часть assert'ов включенных в Release. Для этого их обычно разбивают на классы "быстрые", "медленные", "очень медленные" — и уже пользователь библиотеки решает что попадёт в Release.
·>По-моему излишнее усложнение. Собственно на основании чего пользователь будет принимать решение?
1. На основании того какое быстродействие его устраивает
2. На основании того насколько корректен его код (здесь речь идёт про библиотеку и пользовательский код, ассерты внутри библиотеки могут ловить ошибки в пользовательском коде).
| Скрытый текст | |
| https://www.youtube.com/watch?v=1QhtXRMp3Hg https://www.youtube.com/watch?v=tz2khnjnUx8 | |
Re[28]: {@Sinix} Да ну и фиг с этой Java-ой. .Net будет убит
Здравствуйте, ·, Вы писали:
EP>>·>Тут не в сомнениях дело. А сам факт того, что если условие ассерта не сработает в релизе — то угадать что будет — невозможно.
EP>>assert'ы применяются намного шире чем простейший bounds checking — для проверки пред/пост-условий, для проверки инвариантов и вариантов циклов, для проверки инвариантов классов и т.п.
·>А что они дают-то? Почему вместо assert x просто нельзя if(!x) throw Boom()?
Почему нельзя? — Можно (есть конечно случаи где нужен именно no-throw код, иначе в процессе раскрутки поломаются другие инварианты, но это отдельная тема, не особо влияющая на суть данной дискуссии).
Отличительная черта assert'ов — в том что они могут быть опционально отключены, более того — для формально верифицированного кода они не нужны.
·>Если медленно — это уже проблема алгоритма.
Это ещё почему?
·>При хорошем покрытии тестами ценность ассертов падает до нуля.
Точно также как и ценность других defensive примочек, а-ля bounds checking
EP>>С другой стороны, выключение части из проверок в runtime'е, ровно как и отсутствии часть проверок вообще — не делает программу некорректной.
·>Но только если ассерты расставлены корректно.
Что ты имеешь в виду? То что проверка внутри assert'а может иметь side-effect?
EP>>>>ЕМНИП Sinix рассказывал что использует их во всю как раз в managed языке.
EP>>·>Можно, конечно. Но непонятно зачем. А где он об этом писал?
EP>>Много где, можем попробовать его призвать сюда. Например в CodeJam сделали компонент Assertions.
·>Я что-то не понял что это. Судя по if (!condition)throw это не ассерты в понимании С++.
Там некоторые из них опциональные, и не попадают в Release.
EP>>В целом не пойму почему ты проводишь разделение managed/не managed относительно assert'ов.
·>Это в ответ на то, что в С++ "включаются asserts, checked iterators и прочий defensive programming". Ассерты тут как частный случай скорее.
·>Т.е. в managed у тебя всегда работает правильно, а когда может — работает быстро.
Ты как-то перекручиваешь слова. Не "правильно", а раннее обнаружение бага, что вовсе не означает "правильно" — твой код уже пришёл в состояние в котором он быть не должен был, и неизвестно как он туда попал, и что уже натворил по пути.
·>В unmanaged наоборот: когда может — работает правильно, и всегда быстро.
Не всегда быстро, только когда assert'ы отключены.
EP>>·>Они позволяют избежать UB. Грубо говоря некий такой wysiwyg — как код написан, так он и исполняется. А не так, что вышли за границы массива или обратились к неинициализированной памяти — и последствия совершенно непредсказуемы.
EP>>Это лишь только для мизерной части утверждений корректности программы. Если ты не расписал все утверждения корректности, то никакого "WYSIWYG" — очевидно нет
·>Есть конечно. Я говорю о корректности самого кода, а не логических ошибок в алгоритме.
В чём ты видишь отличие? Выход за пределы bounds это есть логическая ошибка, которой в корректном коде нет
·>Т.е. в С++ если видишь, что у тебя в коде написано a = b + c то при известных значениях b==1 и c==2 может случиться, что a!=3 т.к. где-то что-то стрельнуло по памяти из другого треда. В managed — a==3 всегда, доказано верификатором.
Не доказано — ибо точно также используется не-managed код, точно также есть компилятор в котором могут быть баги, и даже железо может сбоить
EP>>P.S. Ничто не мешает оставить часть assert'ов включенных в Release. Для этого их обычно разбивают на классы "быстрые", "медленные", "очень медленные" — и уже пользователь библиотеки решает что попадёт в Release.
·>По-моему излишнее усложнение. Собственно на основании чего пользователь будет принимать решение?
1. На основании того какое быстродействие его устраивает
2. На основании того насколько корректен его код (здесь речь идёт про библиотеку и пользовательский код, ассерты внутри библиотеки могут ловить ошибки в пользовательском коде).
EP>>·>Тут не в сомнениях дело. А сам факт того, что если условие ассерта не сработает в релизе — то угадать что будет — невозможно.
EP>>assert'ы применяются намного шире чем простейший bounds checking — для проверки пред/пост-условий, для проверки инвариантов и вариантов циклов, для проверки инвариантов классов и т.п.
·>А что они дают-то? Почему вместо assert x просто нельзя if(!x) throw Boom()?
Почему нельзя? — Можно (есть конечно случаи где нужен именно no-throw код, иначе в процессе раскрутки поломаются другие инварианты, но это отдельная тема, не особо влияющая на суть данной дискуссии).
Отличительная черта assert'ов — в том что они могут быть опционально отключены, более того — для формально верифицированного кода они не нужны.
·>Если медленно — это уже проблема алгоритма.
Это ещё почему?
·>При хорошем покрытии тестами ценность ассертов падает до нуля.
Точно также как и ценность других defensive примочек, а-ля bounds checking
EP>>С другой стороны, выключение части из проверок в runtime'е, ровно как и отсутствии часть проверок вообще — не делает программу некорректной.
·>Но только если ассерты расставлены корректно.
Что ты имеешь в виду? То что проверка внутри assert'а может иметь side-effect?
EP>>>>ЕМНИП Sinix рассказывал что использует их во всю как раз в managed языке.
EP>>·>Можно, конечно. Но непонятно зачем. А где он об этом писал?
EP>>Много где, можем попробовать его призвать сюда. Например в CodeJam сделали компонент Assertions.
·>Я что-то не понял что это. Судя по if (!condition)throw это не ассерты в понимании С++.
Там некоторые из них опциональные, и не попадают в Release.
EP>>В целом не пойму почему ты проводишь разделение managed/не managed относительно assert'ов.
·>Это в ответ на то, что в С++ "включаются asserts, checked iterators и прочий defensive programming". Ассерты тут как частный случай скорее.
·>Т.е. в managed у тебя всегда работает правильно, а когда может — работает быстро.
Ты как-то перекручиваешь слова. Не "правильно", а раннее обнаружение бага, что вовсе не означает "правильно" — твой код уже пришёл в состояние в котором он быть не должен был, и неизвестно как он туда попал, и что уже натворил по пути.
·>В unmanaged наоборот: когда может — работает правильно, и всегда быстро.
Не всегда быстро, только когда assert'ы отключены.
EP>>·>Они позволяют избежать UB. Грубо говоря некий такой wysiwyg — как код написан, так он и исполняется. А не так, что вышли за границы массива или обратились к неинициализированной памяти — и последствия совершенно непредсказуемы.
EP>>Это лишь только для мизерной части утверждений корректности программы. Если ты не расписал все утверждения корректности, то никакого "WYSIWYG" — очевидно нет
·>Есть конечно. Я говорю о корректности самого кода, а не логических ошибок в алгоритме.
В чём ты видишь отличие? Выход за пределы bounds это есть логическая ошибка, которой в корректном коде нет
·>Т.е. в С++ если видишь, что у тебя в коде написано a = b + c то при известных значениях b==1 и c==2 может случиться, что a!=3 т.к. где-то что-то стрельнуло по памяти из другого треда. В managed — a==3 всегда, доказано верификатором.
Не доказано — ибо точно также используется не-managed код, точно также есть компилятор в котором могут быть баги, и даже железо может сбоить
EP>>P.S. Ничто не мешает оставить часть assert'ов включенных в Release. Для этого их обычно разбивают на классы "быстрые", "медленные", "очень медленные" — и уже пользователь библиотеки решает что попадёт в Release.
·>По-моему излишнее усложнение. Собственно на основании чего пользователь будет принимать решение?
1. На основании того какое быстродействие его устраивает
2. На основании того насколько корректен его код (здесь речь идёт про библиотеку и пользовательский код, ассерты внутри библиотеки могут ловить ошибки в пользовательском коде).
| Скрытый текст | |
| https://www.youtube.com/watch?v=1QhtXRMp3Hg https://www.youtube.com/watch?v=tz2khnjnUx8 | |