Проверка предусловий и assert

Последнее обновление: 04.09.2023

Иногда ошибки, возникающие в процессе работы программы, могут быть очень критичными для работы приложения, а их обработка может быть слишком сложной и требовать много кода. Но при этом подобные ошибки могут быть очень редки, веорятность, что они произойдут в программе, очень низка. Соответственно возникает вопрос, определять ли дополнительный код для обработки ошибки, которая довольна критична, но при этом ее вероятность довольно низка, либо поступить как-то по другому. Особенно учитывая, что любой дополнительный код в принципе усложняет программу и снижает ее читабельность.

Одним из выходов из подобной ситуации является прекращение работы программы при возникновении критичной ошибки. Для этого в языке С может применяться функция 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
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850