C中的异常处理 – setjmp()返回0的用途是什么?

我有几个与setjmp / longjmp用法有关的问题 –

> setjmp(jmp ___ buf stackVariables)返回0的用途是什么.这是默认值,我们无法影响.
> setjmp(stackVariables)的唯一意义是在stackVariables中推送堆栈.基本上0告诉我们堆栈是否已成功推送到stack_variables.
>当你从longjmp返回时,它们有一次是非零(任何非零)的值.什么是从lomgjmp返回,何时从longjmp返回,处理异常时.这种设置真的令人困惑.
>有些人可以将它与try / throw和catch联系起来.如果可以提供一些很好的setjmp / longjmp示例,那将会非常棒.
> longJmp是否像throw一样,并且在可以引发异常的地方之后调用它.

谢谢.

解决方法

C99规范给出:

If the return is from a direct invocation,the setjmp macro returns the value zero. If the
return is from a call to the longjmp function,the setjmp macro returns a nonzero
value.

所以1的答案是零表示你第一次调用setjmp,非零表示它从longjmp返回.

>它推动了当前的程序状态.在longjmp之后,状态恢复,控制返回到它被调用的点,并且返回值不为零.
> C中没有例外.它类似于fork返回不同的值,这取决于您是否处于原始进程中,或者是继承环境的第二个进程,如果您熟悉它.
> C中的try / catch将在throw和catch之间的所有自动对象上调用析构函数. setjmp / longjmp不会调用析构函数,因为它们在C中不存在.所以你可以独立调用任何你在同一时间编写的任何内容.

有了这个附带条件,这个:

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

void foo ( char** data ) ;
void handle ( char* data ) ;
jmp_buf env;

int main ()
{
    char* data = 0;

    int res = setjmp ( env ); 
    // stored for demo purposes. 
    // in portable code do not store 
    // the result,but test it directly.

    printf ( "setjmp returned %d\n",res );

    if ( res == 0 )
        foo ( &data );
    else
        handle ( data );

    return 0;
}


void foo ( char** data )
{
    *data = malloc ( 32 );

    printf ( "in foo\n" );

    strcpy ( *data,"Hello World" );

    printf ( "data = %s\n",*data );

    longjmp ( env,42 );
}

void handle ( char* data )
{
    printf ( "in handler\n" );

    if ( data ) {
        free ( data );
        printf ( "data freed\n" );
    }
}

大致相当于

#include <iostream>

void foo ( ) ;
void handle ( ) ;

int main ()
{
    try {
        foo ();
    } catch (int x) {
        std::cout << "caught " << x << "\n";
        handle ();
    }

    return 0;
}

void foo ( )
{
    printf ( "in foo\n" );

    std::string data = "Hello World";

    std::cout << "data = " << data << "\n";

    throw 42;
}

void handle ( )
{
    std::cout << "in handler\n";
}

在C情况下,你必须进行显式的内存管理(虽然通常你在调用longjmp之前将它释放到malloc中的函数中,因为它使生活更简单)

相关文章

/** C+⬑ * 默认成员函数 原来C++类中,有6个默认成员函数: 构造函数 析构函数 拷贝...
#pragma once // 1. 设计一个不能被拷贝的类/* 解析:拷贝只会放生在两个场景中:拷贝构造函数以及赋值运...
C类型转换 C语言:显式和隐式类型转换 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译...
//异常的概念/*抛出异常后必须要捕获,否则终止程序(到最外层后会交给main管理,main的行为就是终止) try...
#pragma once /*Smart pointer 智能指针;灵巧指针 智能指针三大件//1.RAII//2.像指针一样使用//3.拷贝问...
目录&lt;future&gt;future模板类成员函数:promise类promise的使用例程:packaged_task模板类例程...