Иногда ошибки, возникающие в процессе работы программы, могут быть очень критичными для работы приложения, а их обработка может быть слишком сложной и требовать много кода. Но при этом подобные ошибки могут быть очень редки, веорятность, что они произойдут в программе, очень низка. Соответственно возникает вопрос, определять ли дополнительный код для обработки ошибки, которая довольна критична, но при этом ее вероятность довольно низка, либо поступить как-то по другому. Особенно учитывая, что любой дополнительный код в принципе усложняет программу и снижает ее читабельность.
Одним из выходов из подобной ситуации является прекращение работы программы при возникновении критичной ошибки. Для этого в языке С может применяться функция assert(). Например:
void someFunc() { assert(checkСonditions() && "Error! Conditions are incorrect"); // основной код }
В данном коде assert() с помощью некоторой функции checkСonditions()
проверяет некоторые условия, и если они не выполняются,
assert() выводит в стандартный поток ошибок stderr сообщение "Error! Conditions are incorrect". И после этого выполнение программы прерывается.
Подобный способ довольно прост. В частности, его можно применять при проверки предусловий, например, на проверку параметров на NULL. Подобный паттерн иногда называют Assertion Context
Например, возьмем следующюю программу:
#include <stdio.h> void writeTextToFile(char*, char*); int main(void){ char* filename = "test.txt"; char* text = "Hello METANIT.COM"; writeTextToFile(filename, text); } void writeTextToFile(char* file_name, char* text) { // проверка предусловий if(file_name==NULL) // если имя файла не указано, выход из функции { printf("Error! File name is incorrect!\n"); return; } if(text == NULL) // если текст не указан { printf("Error! Text is incorrect!\n"); return; } // открываем файл FILE* file_pointer=fopen(file_name, "w"); if(file_pointer == NULL) // если открытие файла прошло неудачно, выход из функции открыт { printf("Error! Unable to open file!\n"); return; } // запись в файл if(fputs(text, file_pointer)!=EOF) { printf("Success! Text has been written to the file!\n"); } // закрываем файл fclose(file_pointer); }
Здесь функция writeTextToFile()
принимает некоторый текст и записывает его в файл, который также передается через параметр. В начале функции параметры функции проверяются
на значение NULL. И в случае, если хотя бы один параметр равен NULL, функция завершает свою работу. Теперь применим assert:
#include <stdio.h> #include <assert.h>> // для функции assert void writeTextToFile(char*, char*); int main(void){ char* filename = "test.txt"; char* text = "Hello METANIT.COM"; writeTextToFile(filename, text); } void writeTextToFile(char* file_name, char* text) { // проверка предусловий assert(file_name!=NULL && "Error! File name is incorrect!\n"); // если имя файла не указано, выход из функции assert(text != NULL && "Error! Text is incorrect!\n"); // если текст не указан // открываем файл FILE* file_pointer=fopen(file_name, "w"); if(file_pointer == NULL) // если открытие файла прошло неудачно, выход из функции открыт { printf("Error! Unable to open file!\n"); return; } // запись в файл if(fputs(text, file_pointer)!=EOF) { printf("Success! Text has been written to the file!\n"); } // закрываем файл fclose(file_pointer); }
Таким образом, если выполняются условия file_name!=NULL
и text != NULL
, то функция продолжает свою работу - записывает строку в файл. Если хотя бы одно из условий
не выполняется, то функция завершает работу, а на консоль выводится сообщение. Например, если file_name = 0, выводится сообщение следующего типа:
Assertion failed: file_name!=NULL && "Error! File name is incorrect!\n", file app.c, line 15