Большая часть моего опыта связана с относительно ограниченными системами, где раздувание кода такого рода нежелательно. Поэтому мой собственный инстинкт - либо использовать утверждения только для отладки, либо полностью исключить их. Вы бы надеялись, что любые возможные недопустимые входные данные появятся во время тестирования вызывающего, который выдает вам неверные значения, поэтому при тестировании в режиме отладки, а также в режиме выпуска вы увидите диагностику. В противном случае вы будете отлаживать сбой, когда это произойдет.
Если размер и производительность кода не имеют значения (и почти во всем коде простая проверка на ноль или диапазон в любом случае не повлияет на производительность), то чем больше утверждений вы оставите в своем коде в режиме выпуска, тем больше у вас шансов диагностики неисправностей без необходимости повторного создания ошибки в тестовом режиме. Это может сэкономить много времени. В частности, если ваш продукт представляет собой библиотеку, значительная часть отчетов об ошибках связана с ошибками клиентов, поэтому никакое предварительное тестирование не может предотвратить их появление в открытом доступе. Чем раньше вы сможете доказать клиенту, что его код неверен, тем быстрее он сможет это исправить, и вы сможете вернуться к поиску собственных ошибок.
Тем не менее, в C / C ++ я нахожу, что конкретный случай проверки на нулевые указатели является лишь незначительной помощью. Если кто-то передает вам указатель, то условие полной действительности не "не должно быть нулевым". Он должен указывать на память, которая может быть прочитана (возможно, также записана) текущим процессом до определенного размера и содержит правильный тип объекта, возможно, в определенном подмножестве всех возможных состояний. Его не нужно освобождать, не уничтожать из-за переполнения буфера в другом месте, возможно, чтобы он не был одновременно изменен другим потоком и т. Д. Вы не собираетесь проверять все это при входе в метод, поэтому вы все равно можете пропустить неверный параметры. Все, что заставляет вас или других программистов думать, что «этот указатель не является нулевым, поэтому он должен быть действительным», поскольку вы протестировали только одну небольшую часть условия допустимости, вводит в заблуждение.
Если вы вообще проходите указателем, значит, вы уже находитесь на территории, где вам нужно доверять вызывающей стороне, чтобы она не давала вам мусор. Отказ от одного конкретного экземпляра мусора все еще оставляет вас верить, что вызывающий абонент не даст вам ни одного из множества других видов мусора, который они могут вызвать, который сложнее обнаружить. Если вы обнаружите, что нулевые указатели являются распространенным видом мусора от ваших конкретных абонентов, то непременно проверьте их, поскольку это экономит время на диагностику ошибок в других частях системы. Это зависит от оценки того, стоит ли находить ошибки в коде вашего вызывающего с симптомом «передает мне нулевой указатель», стоит ли вздувать ваш собственный код (возможно, в двоичном размере и, конечно, в исходном коде): если такие ошибки редки, то вы ' Вы, вероятно, тратите время и проверяете их на предмет проверки недвижимости.
Конечно, в некоторых языках вы не проходите мимо указателя, и у вызывающей стороны есть только ограниченные возможности повредить память, поэтому меньше мусора. Но в Java, например, передача неправильного объекта все еще является более распространенной ошибкой программирования, чем передача ошибочного нуля. В любом случае, значения Null обычно довольно легко диагностировать, если оставить их на время выполнения, чтобы определить их и посмотреть на трассировку стека. Таким образом, значение нулевой проверки весьма ограничено даже там. В C ++ и C # вы можете использовать передачу по ссылке, где нулевые значения будут запрещены.
То же самое относится к любому другому конкретному неверному вводу, который вы можете проверить, и к любому языку. Полное тестирование до и после условия (если возможно) - это, конечно, другое дело, поскольку, если вы можете протестировать весь контракт на вызовы, вы окажетесь на более устойчивой основе. И если вы можете использовать ткачество или что-то еще, чтобы утверждать контракты, не добавляя к исходному коду самой функции, это еще лучше.