Существует разница между ошибкой logi c и ошибкой утверждения. Если вашей функции разрешено запускаться только с допустимым указателем, то пользователь вашей функции несет ответственность и должен проверить, является ли это действительным указателем, прежде чем вводить вашу функцию. Стандартные функции C документируют такие состояния, как «неопределенное поведение», потому что буквально не определено, как strcpy(NULL, "abc")
должен реагировать - передача таких значений функциям просто недопустима, и программист (другой код) несет ответственность за проверку таких ошибок.
Если так, то здесь assert()
вступает в игру. assert
предназначался для срабатывания только в отладочной конфигурации вашего проекта и должен быть удален (чтобы не снижалась производительность) в выпускной конфигурации вашего проекта - отсюда и макрос NDEBUG
. Принципы НАСА критического для безопасности кода сообщает, что «плотность утверждений кода должна составлять минимум два утверждения на функцию».
Итак, если передача NULL вашей функции является «недопустимым состоянием», в этом случае поведение вашей функции «не определено», потому что просто не имеет смысла передавать NULL (или любой другой недопустимый указатель), я обычно пишу:
struct Vector3 {
float x,y,z;
};
void test(struct Vector3 *va, struct Vector3 *vb) {
assert(va != NULL);
assert(vb != NULL);
// bla bla...
}
(и на g cc Я бы добавил __attribute__((__nonnull__))
, а с новейшим g cc с -std=c2x
мы можем [[gnu::nonnull]]
). Имейте в виду, что assert()
расширяется до «ничего», когда NDEBUG
определено (ie. Выражение не вычисляется), поэтому не помещайте операторы с побочными эффектами внутри assert()
.