|
4 | 4 |
|
5 | 5 | ```cpp |
6 | 6 | # if !defined(NDEBUG) |
7 | | - #define assert(expr) implementation-defined |
| 7 | + #define assert(expr) implementation-defined // (1) C++03 |
| 8 | + #define assert(...) implementation-defined // (1) C++26 |
8 | 9 | # else |
9 | | - #define assert(ignore) ((void)0) |
| 10 | + #define assert(ignore) ((void)0) // (2) C++03 |
| 11 | + #define assert(...) ((void)0) // (2) C++26 |
10 | 12 | # endif |
11 | 13 | ``` |
12 | 14 |
|
|
19 | 21 |
|
20 | 22 |
|
21 | 23 | ## 要件 |
22 | | -パラメータの式の型はスカラ型でなければならない。 |
| 24 | +- C++14まで : パラメータの式の型はスカラ型でなければならない |
| 25 | + - C言語への参照として定義されていた仕様では、`assert`は`void assert(scalar expression);`のような関数として定義されていた |
23 | 26 |
|
24 | 27 |
|
25 | 28 | ## 効果 |
26 | 29 | - 有効な場合: |
27 | | - - パラメータの式を評価し、偽であった場合(`0`と等しい場合)、式をテキスト化したものに加え`__FILE__`, `__LINE__`, `__func__`の値を標準エラー出力に処理系定義の書式で書き込み、[`abort()`](/reference/cstdlib/abort.md)関数を呼び出してプログラムを異常終了させる。 |
| 30 | + - C++03 : パラメータの式を評価し、 |
| 31 | + - C++26 : 可変引数パラメータ`__VA_ARGS__`を`bool`に変換し、 |
| 32 | + - 真に評価された場合は、なにもしない |
| 33 | + - そうでない場合(`0`と等しい場合)、式をテキスト化したもの、([`std::source_location`](/reference/source_location/source_location.md)`::`[`current()`](/reference/source_location/source_location/current.md)で取得できるような) ソースファイル名、行番号、関数名を標準エラー出力に処理系定義の書式で書き込み、[`abort()`](/reference/cstdlib/abort.md)関数を呼び出してプログラムを異常終了させる |
28 | 34 | - 無効な場合: |
29 | | - - パラメータの式は評価はされず、何もしない。 |
| 35 | + - パラメータの式は評価はされず、なにもしない |
30 | 36 |
|
31 | 37 | このマクロは、定数式内で使用できる。(C++17) |
32 | 38 |
|
@@ -89,11 +95,35 @@ int main() |
89 | 95 | ``` |
90 | 96 | ``` |
91 | 97 |
|
| 98 | +### カンマを含む条件式をassertマクロで使用する (C++26) |
| 99 | +```cpp example |
| 100 | +#include <cassert> |
| 101 | +#include <type_traits> |
| 102 | + |
| 103 | +template <class T> |
| 104 | +void f() |
| 105 | +{ |
| 106 | + assert(std::is_same_v<int, T>); // C++26 : OK |
| 107 | + assert((std::is_same_v<int, T>)); // C++23までは、カンマを含む式は全体を丸カッコで囲む必要がある |
| 108 | +} |
| 109 | + |
| 110 | +int main() |
| 111 | +{ |
| 112 | + f<int>(); |
| 113 | + f<double>(); |
| 114 | +} |
| 115 | +``` |
| 116 | + |
| 117 | +### 出力 |
| 118 | +``` |
| 119 | +``` |
| 120 | + |
92 | 121 |
|
93 | 122 | ## 参照 |
94 | 123 | - C++14 - 19.3 [assertions] |
95 | 124 | ただしC++としての規定はほとんど無く、ほぼ参照規格であるISO C 7.2の規定によるものとなっている。 |
96 | 125 | - [What does it mean for C++ that assert takes a scalar argument?](https://groups.google.com/a/isocpp.org/d/topic/std-discussion/6EHDRo1A2EE/discussion) |
97 | 126 | パラメータの式の型についての要件は参照規格であるCの規定によるものであり、「スカラ型」が[C++におけるスカラ型](/reference/type_traits/is_scalar.md)となるのか、あるいはCにおけるスカラ型の範囲に限定されるのか、少なくともC++14時点でははっきりしていない。 |
98 | 127 | - [LWG Issue 2234. `assert()` should allow usage in constant expressions](http://wg21.cmeerw.net/lwg/issue2234) |
99 | | - |
| 128 | +- [P2264R7 Make `assert()` macro user friendly for C and C++](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2264r7.html) |
| 129 | + - C++26から、カンマを含む式を条件式として使用できるようになった |
0 commit comments