Search code examples
csetjmp

Is there some version of longjmp that can output long values?


I'm working on a framework on C language, for it I want to implement exceptions, for it I'm using longjump with setjump, but on x64 machines longjump still outputs an integer.

I've created a class (struct with vptr essentially), which represents exception, but to throw it out in code I need to throw a pointer to this structure. The pointer has an unsigned long long value (qword) for x64 machines and unsigned int (dword) for x86, so I shall require only qword to be in output to handle the error.

Are there implementations of longjmp and setjmp, which can output qword?

Or maybe I could write my own longjump, but for it the original source code is required.


Solution

  • You can enclose your jmp_buf-typed variable in a larger structure, possibly larger by just sizeof(void*). Then just before calling longjmp() you can store the pointer in that extra space. There's no need to try to squeeze a pointer into an int.

    Example:

    #include <stdio.h>
    #include <setjmp.h>
    
    struct jmp_buf_struct
    {
      jmp_buf jb;
      void* exc_ptr;
    };
    
    void may_throw(jmp_buf jb)
    {
      struct jmp_buf_struct* jbs_ptr = (struct jmp_buf_struct*)jb;
      jbs_ptr->exc_ptr = "Exception message!";
      longjmp(jb, 1);
    }
    
    int main()
    {
      struct jmp_buf_struct jbs;
      if (setjmp(jbs.jb))
      {
        printf("Threw %p = \"%s\".", jbs.exc_ptr, (char*)jbs.exc_ptr);
      }
      else
      {
        may_throw(jbs.jb);
        puts("Didn't throw.");
      }
      return 0;
    }
    

    Output:

    Threw 0x55638ebc78c4 = "Exception message!".