C:
Обробка помилок

Як робити:

У C немає вбудованої підтримки винятків, на відміну від деяких інших мов. Замість цього, він покладається на кілька традиційних стратегій обробки помилок, таких як повернення спеціальних значень з функцій та встановлення глобальних змінних, як от errno.

Повернення спеціальних значень

Функції можуть вказати на помилку, повертаючи певне значення, яке малоймовірно буде валідним результатом. Ось приклад з цілими числами:

#include <stdio.h>

int inverse(int number, double *result) {
    if (number == 0) {
        return -1; // Випадок помилки
    } else {
        *result = 1.0 / number;
        return 0; // Успішно
    }
}

int main() {
    double result;
    if (inverse(0, &result) < 0) {
        printf("Error: Division by zero.\n");
    } else {
        printf("Обернене значення: %f\n", result);
    }
    
    return 0;
}

Вивід:

Error: Division by zero.

Перевірка errno

Для функцій бібліотеки, особливо тих, які взаємодіють з системою або ОС (як-от введення/виведення файлів), errno встановлюється, коли сталася помилка. Для її використання включіть errno.h і перевіряйте errno після підозрюваного збою:

#include <stdio.h>
#include <errno.h>
#include <string.h>

int main() {
    FILE *file = fopen("nonexistent.txt", "r");
    if (file == NULL) {
        printf("Помилка відкриття файлу: %s\n", strerror(errno));
    }
    
    return 0;
}

Вивід:

Помилка відкриття файлу: Немає такого файлу або каталогу

Поглиблений розгляд

Історично мінімалістичний дизайн мови програмування C не включав вбудованого механізму обробки винятків, що відображає її низькорівневе, системне програмування походження, де критично важливі максимальна продуктивність та контроль на найнижчому рівні. Замість цього, C вибрала більш ручний підхід до обробки помилок, який відповідає її філософії надання програмістам максимального контролю, навіть за ціною зручності.

Хоча цей підхід добре узгоджується з дизайнерськими цілями C, він також може призвести до довгих кодів перевірки на помилки та потенційно пропущених перевірок на помилки, які сучасні мови адресують за допомогою структурованих механізмів обробки винятків. Наприклад, винятки в мовах, таких як Java або C#, дозволяють централізовану обробку помилок, роблячи код чистішим і керування помилками простішим. Однак, винятки вносять свої накладні витрати та складність, які можуть бути неідеальними для системного програмування, де C відзначається.

Незважаючи на свою грубість, ця ручна обробка помилок у C вплинула на дизайн управління помилками в багатьох інших мовах, пропонуючи модель, де явність умов помилок може призвести до більш передбачуваного та легкого для відладки коду. Для критичних систем, де збої повинні бути керовані граціозно, парадигма обробки помилок C — у поєднанні з сучасними кращими практиками, як-от бібліотеки обробки помилок та конвенції — забезпечує надійність та безпеку.