C 中的异常处理 - setjmp() 返回 0 有什么用? [英] Exception Handling in C - What is the use of setjmp() returning 0?

查看:25
本文介绍了C 中的异常处理 - setjmp() 返回 0 有什么用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有几个关于 setjmp/longjmp 使用的问题 -

I have a few questions relating to setjmp/longjmp usage -

  1. setjmp(jmp___buf stackVariables)返回0有什么用.这是默认值,我们无法影响.

  1. What is the use of setjmp(jmp___buf stackVariables) returning 0. It is a default, which we cannot influence.

setjmp(stackVariables)的唯一意义就是在stackVariables中压栈.基本上 0 告诉我们堆栈是否成功推送到 stack_variables 上.

Is the only significance of setjmp(stackVariables) is to push the stack in stackVariables. And basically 0 tells us if the stack was pushed on stack_variables successfully.

当您从 longjmp 返回时,它们是非零值(任何非零值)的一种情况.从 lomgjmp 返回什么,何时从 longjmp 返回,何时处理您的异常.这是设置真的很混乱.

Their is one occasion when the value is non-zero (any non-zero) when you return from a longjmp. What is returning from a lomgjmp, when do you return from longjmp, when your exception is handled. This is setup is really confusing.

能否将其与尝试/投掷和接球联系起来.如果能提供一些 setjmp/longjmp 的好例子,那就太好了.

Can some please relate it to try/throw and catch. And would be really great, if some good examples of setjmp/longjmp could be provided.

类似于 throw 的 longJmp,在可以引发异常的地方之后调用.

Is longJmp like throw, and it is called just after the place where exception can be raised.

谢谢.

推荐答案

C99 规范给出:

如果返回来自直接调用,则 setjmp 宏返回值零.如果return 来自对 longjmp 函数的调用,setjmp 宏返回一个非零值价值.

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 返回.

So the answer to 1 is that a zero indicates you have called setjmp the first time, and non-zero indicates it is returning from a longjmp.

  1. 它推送当前程序状态.一个longjmp后,状态恢复,控制回到调用点,返回值非零.

  1. It pushes the current program state. After a longjmp, the state is restored, control returns to the point it was called, and the return value is non-zero.

C 中没有例外.它有点类似于 fork 返回不同的值,具体取决于您是在原始进程中,还是在继承环境的第二个进程中,如果你熟悉的话.

There are no exceptions in C. It's sort-of similar to fork returning different values depending whether you're in the original process, or a second process which has inherited the environment, if you're familiar with that.

try/catch 将在 throw 和 catch 之间的所有自动对象上调用析构函数.setjmp/longjmp 不会调用析构函数,因为它们在 C 中不存在.所以就调用 free您在此期间malloc编辑的任何内容.

try/catch in C++ will call destructors on all automatic objects between the throw and the catch. setjmp/longjmp will not call destructors, as they don't exist in C. So you are on your own as far as calling free on anything you've malloced in the mean time.

附带条件:

#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
", res );

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

    return 0;
}


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

    printf ( "in foo
" );

    strcpy ( *data, "Hello World" );

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

    longjmp ( env, 42 );
}

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

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

大致相当于

#include <iostream>

void foo ( ) ;
void handle ( ) ;

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

    return 0;
}

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

    std::string data = "Hello World";

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

    throw 42;
}

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

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

In the C case, you have to do explicit memory management (though normally you'd free it in the function which malloc'd it before calling longjmp as it makes life simpler)

这篇关于C 中的异常处理 - setjmp() 返回 0 有什么用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆