Чья должна быть возможность проверить предварительные условия?

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

Соглашение идет примерно так: «если вызывающий обеспечивает выполнение предпосылок функции, тогда функция будет вести себя ожидаемым образом и / или вернуть ожидаемые значения».

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

Когда речь заходит о архитектуре и дизайне программного обеспечения, какой из них лучше всего подходит?

Всего 2 ответа


Это ответственность вызывающего. Например, что может сделать реализация strlen , если передана нулевая указатель? Единственное, что он может сделать, это прервать программу, которая является жизнеспособной, если не решительной, опцией в C. На C ++ она может генерировать исключение (но не если оно соответствует стандарту C ++), но рассмотрение этого исключения будет очень сложно. Поэтому единственное разумное решение, позволяющее программе продолжать работать в известном состоянии, заключается в том, чтобы strlen не вызывался с нулевым указателем в качестве параметра, помещая onus для проверки этого на вызывающий код.


Как говорил Нил, проверка является ответственностью вызывающего. Вы сказали,

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

Чтобы описать, почему это не идеальный aproach, я расскажу о примере Нила, который использовал проверку нулевых указателей, передаваемых в strlen , представить два сценария:

  1. Функция, которая называется strlen проверяет ввод заранее.
  2. strlen проверяет свои аргументы внутри, прежде чем работать с ними.

Нет никакой разницы в эффективности между этими двумя методами, если вы делаете один вызов strlen . Однако представьте, что вместо однократного вызова strlen вы вызываете strlen , strstr и другие строковые функции несколько раз подряд. В сценарии 1, если вы используете 1, 2, 10 или 100 вызовов из строковой библиотеки, вам нужно только один раз проверить наличие ошибок. В сценарии 2 каждый вызов вынужден проверять ввод, делая процесс намного медленнее.


Есть идеи?

10000