diff --git a/GLOBAL_DEFINED_WORDS.json b/GLOBAL_DEFINED_WORDS.json index d0356afeec..630f6b6ae2 100644 --- a/GLOBAL_DEFINED_WORDS.json +++ b/GLOBAL_DEFINED_WORDS.json @@ -220,5 +220,13 @@ "ダングリング": { "yomi": "だんぐりんぐ", "desc": "dangling。寿命が尽きた無効なオブジェクトやメモリ領域を、ポインタ・参照・イテレータなどが指し続けている状態のこと。これらにアクセスすると未定義の動作を引き起こす" + }, + "式文": { + "yomi": "しきぶん", + "desc": "expression-statement。式の末尾にセミコロンをつけた文。式文の式は副作用を起こすために評価されることが多いが、値は破棄される。" + }, + "ヌル文": { + "yomi": "ぬるぶん", + "desc": "null-statement。セミコロンだけの式文。ループの本体を空にしたいときなどに使う" } } diff --git a/reference.md b/reference.md index 0263706afc..5be5e40153 100644 --- a/reference.md +++ b/reference.md @@ -229,8 +229,8 @@ | [``](/reference/climits.md) | 整数型の最小値、最大値を表すマクロ | | | [``](/reference/clocale.md) | ロケール | | | [``](/reference/cmath.md) | 数学関数 | | -| `` | ジャンプ処理 | | -| [``](reference/csignal.md) | シグナル | | +| [``](/reference/csetjmp.md) | ジャンプ処理 | | +| [``](/reference/csignal.md) | シグナル | | | `` | アライメント操作のマクロ | C++17で非推奨
C++20で削除 | | `` | 可変引数操作 | | | [``](/reference/stdbit.h.md) | ビット操作 | C++26 | diff --git a/reference/csetjmp.md b/reference/csetjmp.md new file mode 100644 index 0000000000..ff96ce769a --- /dev/null +++ b/reference/csetjmp.md @@ -0,0 +1,21 @@ +# csetjmp +* csetjmp[meta header] + +``ヘッダでは、非ローカルジャンプのための機能を定義する。非ローカルジャンプは、関数呼び出しのスタックを遡って、特定のポイントにジャンプすることを可能にする機能である。 + +## 型 +| 名前 | 説明 | 対応バージョン | +|------|------| ----------------| +| [`jmp_buf`](csetjmp/jmp_buf.md) | 非ローカルジャンプのための環境を保存するための型 | | + +## マクロ +| 名前 | 説明 | 対応バージョン | +|------|------|----------------| +| [`setjmp`](csetjmp/setjmp.md) | 現在の環境を保存するためのマクロ | | +| [`__STDC_VERSION_SETJMP_H__`](csetjmp/stdc_version_setjmp_h.md) | C23に準拠していることを示すマクロ | C++26 | + + +## 関数 +| 名前 | 説明 | 対応バージョン | +|------|------|----------------| +| [`longjmp`](csetjmp/longjmp.md) | `setjmp()`で保存された環境を復元し、ジャンプするための関数 | | diff --git a/reference/csetjmp/jmp_buf.md b/reference/csetjmp/jmp_buf.md new file mode 100644 index 0000000000..792945e779 --- /dev/null +++ b/reference/csetjmp/jmp_buf.md @@ -0,0 +1,54 @@ +# jmp_buf +* std[meta namespace] +* csetjmp[meta header] +* type-alias[meta id-type] + +```cpp +namespace std { + using jmp_buf = unspecified; +} +``` +* unspecified[italic] + +## 概要 + +`jmp_buf`は、非ローカルジャンプ(関数を跨いだジャンプ)を実現するために、現在の実行環境を保存するための配列型である。 + +[`setjmp()`](setjmp.md)マクロによって現在の環境がこの型に保存され、後に[`longjmp()`](longjmp.md)関数がその環境を復元するために使用される。 + +## 例 + +```cpp example +#include +#include + +std::jmp_buf env; + +void inner_function() { + std::cout << "何らかのエラー" << std::endl; + std::longjmp(env, 42); +} + +int main () { + if (setjmp(env) == 0) { + inner_function(); + } else { + std::cout << "エラーから復帰しました" << std::endl; + } + + return 0; +} +``` +* std::jmp_buf[color ff0000] +* std::longjmp[link longjmp.md] +* setjmp[link setjmp.md] + +### 出力 +``` +何らかのエラー +エラーから復帰しました +``` + +## 関連項目 +- [`longjmp()`](longjmp.md) +- [`setjmp()`](setjmp.md) diff --git a/reference/csetjmp/longjmp.md b/reference/csetjmp/longjmp.md new file mode 100644 index 0000000000..c75519be11 --- /dev/null +++ b/reference/csetjmp/longjmp.md @@ -0,0 +1,74 @@ +# longjmp +* csetjmp[meta header] +* std[meta namespace] +* function[meta id-type] + +```cpp +namespace std { + [[noreturn]] void longjmp(jmp_buf env, int val); +} +``` + +## 概要 + +引数`env`に保存された実行環境を復元し、対応する[`setjmp()`](setjmp.md)の呼び出し地点へプログラムの制御を移す(非ローカルジャンプ)。 + +## 効果 + +* `setjmp()`によって第一引数`env`に保存された実行環境(スタックポインタ、プログラムカウンタ等)を復元する。 + +* プログラムの実行地点を、対応する[`setjmp()`](setjmp.md)の呼び出し地点へジャンプさせる。 + +* ジャンプ先の[`setjmp()`](setjmp.md)は、この関数の第二引数`val`を戻り値として返す。ただし、`val`が0の場合は1を返す。 + +## 戻り値 + +この関数は決して返らない。 + +## 備考 + +以下の場合、動作は未定義である。 +* 対応する`setjmp` と `longjmp` の間で、自動記憶域期間を持つ非トリビアルなデストラクタを持つオブジェクトの生存期間が開始し、終了しない場合(ジャンプによってデストラクタを飛ばす場合) +* コルーチンのサスペンションコンテキスト内で呼び出された場合 +* 対応する`setjmp`が存在しない場合(`env`が有効な環境を保存していない場合) +* `longjmp`は、対応する`setjmp`の呼び出しから同一スレッド内で呼び出されなければならない。異なるスレッドから呼び出された場合 +* `setjmp`を呼び出した関数の実行が終了している場合 + +また、`volatile`修飾子のついていない`setjmp`を呼び出した関数に対してローカルな変数で、その値が`setjmp`から`longjmp`の呼び出しの間で変更されたものがある場合、その変数の値は不定となる。 + +## 例 + +```cpp example +#include +#include + +std::jmp_buf env; + +void inner_function() { + std::cout << "何らかのエラー" << std::endl; + std::longjmp(env, 0); // valが0なので、setjmpは1を返す +} + +int main () { + if (setjmp(env) == 0) { + inner_function(); + } else { + std::cout << "エラーから復帰しました" << std::endl; + } + return 0; +} +``` +* std::longjmp[color ff0000] +* setjmp[link setjmp.md] +* std::jmp_buf[link jmp_buf.md] + +### 出力 + +``` +何らかのエラー +エラーから復帰しました +``` + +## 関連項目 +* [`jmp_buf`](jmp_buf.md) +* [`setjmp`](setjmp.md) diff --git a/reference/csetjmp/setjmp.md b/reference/csetjmp/setjmp.md new file mode 100644 index 0000000000..9c43cb7d09 --- /dev/null +++ b/reference/csetjmp/setjmp.md @@ -0,0 +1,81 @@ +# setjmp +* csetjmp[meta header] +* macro[meta id-type] + +```cpp +#define setjmp(env) unspecified +``` +* unspecified[italic] + +## 概要 + +現在の環境を引数`env`に保存するマクロ。 +`env`は、[`jmp_buf`](jmp_buf.md)型のオブジェクトでなければならない。 + +## 事前条件 + +このマクロは以下の文脈でのみ現れる。 + +1. `if`文、`switch`文やループの条件全体 +2. 関係演算子または等価演算子のオペランドの一つ(もう一つのオペランドは整数定数)で、その結果式が1を満たす場合 +3. `!`のオペランドであり、その式が1を満たす場合 +4. 式文の式全体(`void`型へのキャストを含む) + +上記以外の箇所での呼び出しは未定義の動作となる。 + +## 戻り値 + +直接マクロが呼び出された場合、0を返す。 +それ以外([`longjmp`](longjmp.md)関数から)の呼び出しでは非0を返す。 +なお、[`longjmp`](longjmp.md)関数の第二引数が0の場合は、1を返す。 + +## 備考 + +* 対応する`setjmp` と `longjmp` の間で、自動記憶域期間を持つ非トリビアルなデストラクタを持つオブジェクトの生存期間が開始し、終了しない場合(ジャンプによってデストラクタを飛ばす場合)、その動作は未定義である。 +* コルーチンのサスペンションコンテキスト内で呼び出された場合、動作は未定義である。 + +また、`volatile`修飾子のついていない`setjmp`を呼び出した関数に対してローカルな変数で、その値が`setjmp`から`longjmp`の呼び出しの間で変更されたものがある場合、その変数の値は不定となる。 + + +## 例 + +```cpp example +#include +#include + +std::jmp_buf env; + +void inner_function() { + std::cout << "何らかのエラー" << std::endl; + std::longjmp(env, 42); +} + +int main () { + if (setjmp(env) == 0) { + inner_function(); + } else { + std::cout << "エラーから復帰しました" << std::endl; + } + + return 0; +} +``` +* setjmp[color ff0000] +* std::longjmp[link longjmp.md] +* std::jmp_buf[link jmp_buf.md] + + +### 出力 + +``` +何らかのエラー +エラーから復帰しました +``` + +## 参照 + +[MSC22-C. setjmp()、longjmp() の機能を安全に使用する](https://www.jpcert.or.jp/sc-rules/c-msc22-c.html#:~:text=%E4%BB%A3%E5%85%A5%E6%96%87%E3%81%A7%20setjmp()%20%E3%82%92%E5%91%BC%E3%81%B3%E5%87%BA%E3%81%97%E3%81%A6%E3%81%8A%E3%82%8A%E3%80%81%E7%B5%90%E6%9E%9C%E3%81%A8%E3%81%97%E3%81%A6%E6%9C%AA%E5%AE%9A%E7%BE%A9%E3%81%AE%E5%8B%95%E4%BD%9C%E3%81%8C%E5%BC%95%E3%81%8D%E8%B5%B7%E3%81%93%E3%81%95%E3%82%8C%E3%82%8B) + +## 関連項目 +- [jmp_buf](/reference/csetjmp/jmp_buf.md) +- [longjmp](/reference/csetjmp/longjmp.md) diff --git a/reference/csetjmp/stdc_version_setjmp_h.md b/reference/csetjmp/stdc_version_setjmp_h.md new file mode 100644 index 0000000000..486a10fb1c --- /dev/null +++ b/reference/csetjmp/stdc_version_setjmp_h.md @@ -0,0 +1,11 @@ +# \_\_STDC_VERSION_SETJMP_H__ +* csetjmp[meta header] +* macro[meta id-type] +* cpp26[meta cpp] + +```cpp +#define __STDC_VERSION_SETJMP_H__ 202311L +``` + +## 概要 +``ヘッダがC23の基準に準拠していることを示すマクロ。