Evgenii Legotckoi
02 січня 2018 р. 15:33

C++ - Підручник 012. static_assert, перевірка помилок під час компіляції

Винятки викидаються під час виконання програми, якщо помилка може бути знайдена під час компіляції програми, то можна використовувати static_assert , який повідомить про необхідність поправити програмний код у ключових місцях.

Використання static_assert буде виглядати наступним чином.

  1. static_assert(4<=sizeof(int), "integers are too small"); // проверка размера integer

Синтаксис буде наступним static_assert(A, B); де

  • A - це умова, за якої викидатиметься помилка в тому випадку, якщо A дорівнює false
  • B - це текст повідомлення про помилку

Застосування

static_assert може бути корисним при використанні констант та константних виразів, які обчислюються на етапі компіляції.

У цьому коді проводиться перевірка локальної константної швидкості, яка не може бути швидше за швидкість світла.

  1. constexpr double C = 299792.458; // km/s, скорость света
  2.  
  3. void f(double speed)
  4. {
  5. const double local_max = 160.0/(6060); // 160 km/h == 160.0/(60*60) km/s
  6. static_assert(speed<C,"can't go that fast"); // error: speed должна быть константой
  7. static_assert(local_max<C,"не может двигаться быстрее"); // OK
  8. }

Також можна використовувати цю перевірку в ключових місцях для перерахувань. Наприклад, дано такий перелік.

  1. enum Types
  2. {
  3. E_BEGIN_TYPES,
  4. E_A = E_BEGIN_TYPES,
  5. E_B,
  6. E_C,
  7. E_D,
  8. E_END_TYPES = E_D
  9. };

І є наступний метод чи функція в якомусь місці коду

  1. QString getStandardMessage(Types type)
  2. {
  3. static_assert(E_END_TYPES == 3, "Need to implement method for new type");
  4.  
  5. switch (type)
  6. {
  7. case E_A: return "Type A";
  8. case E_B: return "Type B";
  9. case E_C: return "Type C";
  10. case E_D: return "Type D";
  11. default: return "Type is not implemented";
  12. }
  13. }

В даному випадку ми знаємо, що останні перерахування, тобто E_D або E_END_TYPES дорівнюватимуть 3. І виняток під час компіляції викинуто не буде. Але як тільки буде додано новий учасник цього переліку.

  1. enum Types
  2. {
  3. E_BEGIN_TYPES,
  4. E_A = E_BEGIN_TYPES,
  5. E_B,
  6. E_C,
  7. E_D,
  8. E_E, // Новый участник перечисления
  9. E_END_TYPES = E_E
  10. };

То static_assert викине помилку, яка означатиме, що ми забули виправити цей метод. Виправлення буде виглядати так.

  1. QString getStandardMessage(Types type)
  2. {
  3. static_assert(E_END_TYPES == 4, "Need to implement method for new type");
  4.  
  5. switch (type)
  6. {
  7. case E_A: return "Type A";
  8. case E_B: return "Type B";
  9. case E_C: return "Type C";
  10. case E_D: return "Type D";
  11. case E_E: return "Type E";
  12. default: return "Type is not implemented";
  13. }
  14. }

У цьому методі ми додамо реалізацію коду типу E_E, і навіть поправимо сам static_assert, щоб він враховував кількість учасників перерахування з новим учасником.

Рекомендовані статті на цю тему

По статті запитували0питання

1

Вам це подобається? Поділіться в соціальних мережах!

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up
  • Останні коментарі
  • Evgenii Legotckoi
    16 квітня 2025 р. 17:08
    Благодарю за отзыв. И вам желаю всяческих успехов!
  • IscanderChe
    12 квітня 2025 р. 17:12
    Добрый день. Спасибо Вам за этот проект и отдельно за ответы на форуме, которые мне очень помогли в некоммерческих пет-проектах. Профессиональным программистом я так и не стал, но узнал мно…
  • AK
    01 квітня 2025 р. 11:41
    Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
  • Evgenii Legotckoi
    09 березня 2025 р. 21:02
    К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
  • VP
    09 березня 2025 р. 16:14
    Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…