pointers yay!
Mar. 30th, 2011 12:04 amеще раз убедился, что софт, претендующий на сколько-нибудь надежность (при больших размерах codebase) писать на С/C++ не стоит.
См. красиво и детально описанный срач на http://avva.livejournal.com/2323823.html, а также коммент http://avva.livejournal.com/2323823.html?thread=78031215#t78031215
no subject
Date: 2011-03-29 11:40 pm (UTC)По-моему, описанная проблема C/C++-независима. Что не опровергает твоего вывода :)
По сабжу: имхо, разработчики libc должны волевым решением «пропатчить» (дополнить, ужесточить) свою спецификацию, закрепив де-юро в ней те предположения, на которые закладываются де-факто многие разработчики. Такой патч стандарта не будет ломающим, т.е. код тех разработчиков, которые использовали официальную спецификацию (в частности, не закладывались на неопределённое поведение), не перестанет ей удовлетворять.
Далее, если самим разработчикам libc так уж необходим оптимизированный вариант, заводят свою «приватную» (насколько это достижимо в Си) версию функции
memcpy, которая выбирает стратегию копирования в зависимости от архитектуры и не выполняет проверок (они всегда могут переложить гарантию удовлетворения предусловий на вызывающую сторону, так как это они сами и есть). И пусть используют эту версию в хвост и в гриву. Если хотят предоставить доступ к подобной оптимизации публике, делают ещё одну (нестандартную) версию безопасной функцииmemmoveс проверкой аргументов и вызовомprivate_memcpy_optimized_unsafe.no subject
Date: 2011-03-30 12:10 am (UTC)Ассерты и проверки *принципиально* отличаются
Date: 2011-03-30 07:54 am (UTC)Нет. Аргументы, приходящие извне, нужно полноценно проверять. Ассертить можно аргументы «приватных» функций, контекст вызова которых полностью контролируется «ассертящей стороной». Условно говоря (на C#):
// Метод API, вызов которого нельзя контролировать (аргументы приходят из «недоверенной зоны»). public void Foo(int x) { // Проверка на usage error. if (x < 0) throw new ArgumentOutOfRangeException(...); FooUnsafe(x); } // Метод реализации, вызов которого осуществляют только авторы библиотеки (аргументы приходят из «доверенной зоны»). private void FooUnsafe(int x) { // Проверка на logic error. Debug.Assert(x < 0, ...); ... }Если падает первая проверка, значит виноват пользователь. Исправление будет в пользовательском коде, в месте вызова.
Если падает вторая проверка, значит виновата библиотека. Исправление должно быть в библиотечном коде.
В своём коде разработчики библиотеки не вызывают публичный метод — зачем им внутри функции повторно проверять аргументы, когда они должны обеспечить их корректность по построению?
Re: Ассерты и проверки *принципиально* отличаются
Date: 2011-03-30 03:33 pm (UTC)Я имел в виду, что в случае с memcpy аргументы по сути корректные.
Re: Ассерты и проверки *принципиально* отличаются
Date: 2011-03-31 01:36 pm (UTC)