6

I would like to use setjmp and longjmp in a C program that links to a library that is implemented in C++ (but has a C API).

The C++ code does do dynamic memory allocation and pointers get passed through the API, but as long as the C side of the code manages those (opaque) objects correctly, there shouldn't be any messing up when using longjmp, right?

I know it's not safe to use these functions in C++ code, but should it be safe in C code that is linked to C++ code?

Posco Grubb
  • 522
  • 2
  • 7
  • 20

3 Answers3

4

The fact that you call C++ functions from your C code does not make setjmp and longjmp more unsafe than they always are.

What's important is that if your library allocates resources you must have recovery code in place to ensure that those are released properly after longjmp is called. While this is likely easy for your own allocations, it may be hard or impossible for the C++ library depending on how the C interface you use is structured.

Miguel Grinberg
  • 65,299
  • 14
  • 133
  • 152
  • Ok. My thinking is that as long as those allocations made in the C++ library have a way to be cleaned up via appropriate C-interface calls, the C++ code is isolated from the effects of longjmp, and exception handling and longjmp can't interfere with each other. (I'm also the implementor of the C++ library.) – Posco Grubb Sep 01 '11 at 05:02
  • If you have exception handling in the C++ library you should make sure any thrown exceptions are caught inside the library, you do not want exceptions to make it out of your C++ code (not sure what would happen if you do that, never tried that). And for releasing the C++ allocations, you will have to figure out what needs releasing from the C code that takes control after the longjmp call. Since you own the app and the library I don't see any issues to make this work. – Miguel Grinberg Sep 01 '11 at 05:12
2

setjmp/longjmp are, in general, not safe for use with C++. They effectively replicate the behavior of exceptions, but without unwinding the stack correctly (for instance, they will not run destructors for objects on stack frames that they forcibly exit). Where possible, use exceptions instead if you've got them.

  • OP isn't trying to use `setjmp`/`longjmp` in C++, but rather a C program that uses some C++ code through a C interface (which presumably masks all the C++-isms into code callable as C, and does so safely). – Chris Lutz Aug 31 '11 at 06:06
  • 2
    Even then, it depends. It'd probably be safe to jump within your own code, but using `longjmp` to exit a callback (for instance) might cause havoc. –  Aug 31 '11 at 06:44
  • Using `longjmp` to exit a callback (unless explicitly given permission to do so) sounds like a bad idea regardless of language. You have to clean up after yourself in C too. – Chris Lutz Aug 31 '11 at 14:56
  • @duskwuff Ok, using it in a callback is dangerous, but that would be the case if I was not mixing languages. Other than that, are there any other cases that make you say "it depends"? – Posco Grubb Sep 01 '11 at 04:58
1

Well, right and not right. longjmp will in general not call destructors, so using it in a code like the following:

void f(jmp_buf jb)
{
  some_cpp_object_with_a_nontrivial_destructor x;
  if (some_condition) longjmp(jb, 2);
  // some other code
}

will make all sorts of bad things happen. If you avoid such situations, you should be OK. (In general, longjmp must not jump across any active stack frames with objects having non-trivial destructors.)

zvrba
  • 24,186
  • 3
  • 55
  • 65
  • My code is C, so I can't define local variables with a type that has a constructor. Therefore your example is not applicable to my question. – Posco Grubb Sep 01 '11 at 04:56
  • You end up in a very similar scenario if you give a callback to a C++ function, and the callback calls longjmp. – zvrba Sep 01 '11 at 07:02