0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【C++Builder】C ランタイムライブラリリファレンス (setjmp.h)

Last updated at Posted at 2024-03-04

非局所分岐 (大域ジャンプ) (Set Jump)

ヘッダ
ファイル
setjmp.h
規格 ANSI C (C89) / C90
概要 通常の関数呼出し及び関数からの復帰の規則を回避するため、マクロ setjmp を定義し、更に 1 つの関数及び 1 つの型を宣言する。

C 言語での goto は関数内ジャンプ (ローカルジャンプ) なので、標準 Pascal で言う所の大域ジャンプは許可されません。

C
#include <stdio.h>

int a = 0;

void proc(void)
{
    a++;
    printf("Count: %d\n", a);
    if (a > 9)
        goto jmp; // NG
}

int main(void)
{
    while (1)
        proc();
jmp:
    return 0;
}

大域ジャンプは Delphi 等の多くの Pascal 処理系で許可されていません。

Pascal/Delphi
program JmpTest(output);
label
  99;
var
  a: Integer;
  procedure proc;
  begin
    a := a + 1;
    writeln('Count: ', a);
    if a > 9 then
      goto 99; { Standard Pascal: OK }
  end;         { Delphi         : NG }
begin
  a := 0;
  while True do
    proc;
99:
end.

プラグマ

名前 機能
jmp_buf ローカルでないジャンプ (大域ジャンプ) のためのバッファ (処理系定義の構造体型配列)。

マクロ

引数付きマクロ

名前 機能
setjmp() ローカルでないジャンプ (大域ジャンプ) を設定します。

関数

名前 機能
longjmp() ローカルでないジャンプ (大域ジャンプ) を実行します。

非局所分岐 (大域ジャンプ) は主に深くネストした関数呼び出しから抜ける目的で使用されます。

if (setjmp(env) == 0) {
    // 直接呼び出された時
} else {
    // longjmp() が呼び出された時
}

先述のうまく動作しなかったコードを setjmp()longjmp() で書き替えてみました。

#include <stdio.h>
#include <setjmp.h>

int a = 0;
jmp_buf env;

void proc(void)
{
    a++;
    printf("Count: %d\n", a);
    if (a > 9)
        longjmp(env, 1);
}

int main(void)
{
    if (setjmp(env) == 0) {
        while (1)
            proc();
    }
    return 0;
}

資料


⇦ インデックスへ


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?