The Alpha editions of Visual C++ are especially sensitive to ANSI-compliant use of the _ _setjmp macro. There are two reasons for this: portability and performance. Only ANSI-compliant usage of _ _setjmp is truly portable across platforms, and noncompliant use can result in degraded application performance.
The American National Standards Institute (ANSI) standard explains that:
“..._ _setjmp be usable like any other function, im.e., that it be callable in any expression context, and that the expression evaluate correctly whether the return from _ _setjmp is direct or via a call to _ _longjmp.
Unfortunately, any implementation of _ _setjmp as a conventionally called function cannot know enough about the calling environment to save any temporary registers or dynamic stack locations used part way through an expression evaluation. (A _ _setjmp macro seems to help only if it expands to inline assembly code or a call to a special built-in function.) The temporaries may be correct on the initial call to _ _setjmp, but are not likely to be on any return initiated by a corresponding call to _ _longjmp. These considerations dictated the constraint that _ _setjmp be called only within fairly simple expressions, ones not likely to need temporary storage.
Other uses have undefined behavior and are not portable.”
This undefined behavior varies between the x86 and Alpha versions of Visual C++. An Alpha compiler may issue error or warning messages for non-ANSI uses of _ _setjmp that work without error with the x86 compiler.
As a result, on Alpha, ANSI-compliant use of _ _setjmp must be adhered to as described in the following excerpt from the ANSI standard:
“An invocation of the _ _setjmp macro shall appear only in one of the following contexts:
The entire controlling expression of a selection or iteration statement.
One operand of a relational or equality operator with the other operand an integral constant expression, with the resulting expression being the entire controlling expression of a selection or iteration statement.
The operand of a unary ! operator with the resulting expression being the entire controlling expression of a selection or iteration statement.
The entire expression of an expression statement (possibly cast to void).”