Chris Lutz
Chris Lutz

Reputation: 75429

Legal uses of setjmp and GCC

Using GCC (4.0 for me), is this legal:

if(__builtin_expect(setjmp(buf) != 0, 1))
  {
    // handle error
  }
else
  {
    // do action
  }

I found a discussion saying it caused a problem for GCC back in 2003, but I would imagine that they would have fixed it by now. The C standard says that it's illegal to use setjmp unless it's one of four conditions, the relevant one being this:

  • one operand of a relational or equality operator with the other operand an integer constant expression, with the resulting expression being the entire controlling expression of a selection or iteration statement;

But if this is a GCC extension, can I guarantee that it will work under for GCC, since it's already nonstandard functionality? I tested it and it seemed to work, though I don't know how much testing I'd have to do to actually break it. (I'm hiding the call to __builtin_expect behind a macro, which is defined as a no-op for non-GCC, so it would be perfectly legal for other compilers.)

Upvotes: 2

Views: 1546

Answers (2)

nategoose
nategoose

Reputation: 12392

I think that what the standard was talking about was to account for doing something like this:

int x = printf("howdy");
if (setjmp(buf) != x ) {
    function_that_might_call_longjmp_with_x(buf, x);
} else {
    do_something_about_them_errors();
}

In this case you could not rely on x having the value that it was assigned in the previous line anymore. The compiler may have moved the place where x had been (reusing the register it had been in, or something), so the code that did the comparison would be looking in the wrong spot. (you could save x to another variable, and then reassign x to something else before calling the function, which might make the problem more obvious)

In your code you could have written it as:

int conditional;
conditional = setjump(buf) != 0 ;
if(__builtin_expect( conditional, 1)) {
    // handle error
} else {
    // do action
}

And I think that we can satisfy ourselves that the line of code that assigns the variable conditional meets that requirement.

Upvotes: 1

Joshua
Joshua

Reputation: 43317

But if this is a GCC extension, can I guarantee that it will work under for GCC, since it's already nonstandard functionality? I tested it and it seemed to work, though I don't know how much testing I'd have to do to actually break it. (I'm hiding the call to __builtin_expect behind a macro, which is defined as a no-op for non-GCC, so it would be perfectly legal for other compilers.)

You are correct, __builtin_expect should be a macro no-op for other compilers so the result is still defined.

Upvotes: 0

Related Questions