Namespaces
Variants

static_assert declaration (since C++11)

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Выполняет проверку утверждений на этапе компиляции.

Содержание

Синтаксис

static_assert( bool-constexpr , unevaluated-string ) (1)
static_assert( bool-constexpr ) (2) (начиная с C++17)
static_assert( bool-constexpr , constant-expression ) (3) (начиная с C++26)

Объявляет статическое утверждение. Если утверждение не выполняется, программа является некорректной, и может быть сгенерировано диагностическое сообщение об ошибке.

1) Статическое утверждение с фиксированным сообщением об ошибке.
2) Статическое утверждение без сообщения об ошибке.
3) Статическое утверждение с пользовательским сообщением об ошибке.
Данный синтаксис может быть сопоставлен только если синтаксис ( 1 ) не соответствует.

Объяснение

bool-constexpr -

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

(до C++23)

выражение контекстно преобразуемое к bool , где преобразование является константным выражением

(начиная с C++23)
unevaluated-string - невычисляемый строковый литерал , который будет отображаться как сообщение об ошибке
constant-expression - константное выражение msg , удовлетворяющее всем следующим условиям:
  • msg. size ( ) неявно преобразуемо к std::size_t .
  • msg. data ( ) неявно преобразуемо к const char * .

Объявление static_assert может появляться в области видимости пространства имён и блока (scope) (как объявление блока ) и внутри тела класса (как объявление члена ).

Если bool-constexpr является корректно сформированным и вычисляется в true , или вычисляется в контексте определения шаблона и шаблон не инстанцирован, данное объявление не имеет эффекта. В противном случае возникает ошибка компиляции, и предоставленное пользователем сообщение (если есть) включается в диагностическое сообщение.

Текст предоставленного пользователем сообщения определяется следующим образом:

  • Если сообщение соответствует синтаксическим требованиям unevaluated-string , текст сообщения является текстом unevaluated-string .
  • В противном случае, заданы следующие значения:
Текст сообщения формируется последовательностью из len code units , начиная с ptr , в ordinary literal encoding . Для каждого целого числа i в [ 0 , len ) , ptr [ i ] должно быть integral constant expression .
(since C++26)

Примечания

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

Поскольку сообщение об ошибке должно быть строковым литералом, оно не может содержать динамическую информацию или даже константное выражение , которое само не является строковым литералом. В частности, оно не может содержать имя аргумента шаблонного типа .

(до C++26)
Макрос тестирования возможностей Значение Стандарт Возможность
__cpp_static_assert 200410L (C++11) static_assert (синтаксис ( 1 ) )
201411L (C++17) Однопараметрический static_assert (синтаксис ( 2 ) )
202306L (C++26) Пользовательские сообщения об ошибках (синтаксис ( 3 ) )

Ключевые слова

static_assert

Пример

#include <format>
#include <type_traits>
static_assert(03301 == 1729); // начиная с C++17 строка сообщения является необязательной
template<class T>
void swap(T& a, T& b) noexcept
{
    static_assert(std::is_copy_constructible_v<T>,
                  "Swap requires copying");
    static_assert(std::is_nothrow_copy_constructible_v<T> &&
                  std::is_nothrow_copy_assignable_v<T>,
                  "Swap requires nothrow copy/assign");
    auto c = b;
    b = a;
    a = c;
}
template<class T>
struct data_structure
{
    static_assert(std::is_default_constructible_v<T>,
                  "Data structure requires default-constructible elements");
};
template<class>
constexpr bool dependent_false = false; // обходное решение до CWG2518/P2593R1
template<class T>
struct bad_type
{
    static_assert(dependent_false<T>, "error on instantiation, workaround");
    static_assert(false, "error on instantiation"); // OK благодаря CWG2518/P2593R1
};
struct no_copy
{
    no_copy(const no_copy&) = delete;
    no_copy() = default;
};
struct no_default
{
    no_default() = delete;
};
#if __cpp_static_assert >= 202306L
// Еще не настоящий C++ (std::format должен быть constexpr для работы):
static_assert(sizeof(int) == 4, std::format("Expected 4, got {}", sizeof(int)));
#endif
int main()
{
    int a, b;
    swap(a, b);
    no_copy nc_a, nc_b;
    swap(nc_a, nc_b); // 1
    [[maybe_unused]] data_structure<int> ds_ok;
    [[maybe_unused]] data_structure<no_default> ds_error; // 2
}

Возможный вывод:

1: error: static assertion failed: Swap requires copying
2: error: static assertion failed: Data structure requires default-constructible elements
3: error: static assertion failed: Expected 4, got 2

Отчёты о дефектах

Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены задним числом к ранее опубликованным стандартам C++.

DR Применяется к Поведение в опубликованной версии Корректное поведение
CWG 2039 C++11 только выражение до преобразования должно быть константным преобразование также должно быть
допустимо в константном выражении
CWG 2518
( P2593R1 )
C++11 неинстанцированный static_assert ( false , "" ) ; был некорректным сделан корректным

Ссылки

  • Стандарт C++23 (ISO/IEC 14882:2024):
  • 9.1 Преамбула [dcl.pre] (стр: 10)
  • Стандарт C++20 (ISO/IEC 14882:2020):
  • 9.1 Преамбула [dcl.pre] (стр: 6)
  • Стандарт C++17 (ISO/IEC 14882:2017):
  • 10 Объявления [dcl.dcl] (стр.: 6)
  • Стандарт C++14 (ISO/IEC 14882:2014):
  • 7 Объявления [dcl.dcl] (стр: 4)
  • Стандарт C++11 (ISO/IEC 14882:2011):
  • 7 Объявления [dcl.dcl] (стр: 4)

Смотрите также

выводит заданное сообщение об ошибке и делает программу некорректной
(директива препроцессора)
аварийно завершает программу, если заданное пользователем условие не true . Может быть отключен для релизных сборок.
(функциональный макрос)
contract_assert statement (C++26) проверяет внутреннее условие во время выполнения
(C++11)
условно удаляет перегрузку функции или специализацию шаблона из разрешения перегрузки
(шаблон класса)
Type traits (C++11) определяют интерфейсы на основе шаблонов времени компиляции для запроса свойств типов
Документация C для Статическое утверждение