When the compiler generates an abort for runtime-undefined code, the abort can be executed too soon when side-effects before the undefined behavior might have caused the undefined behavior not to happen after all.
For calls to functions cast to incompatible types, the undefined behavior happens when the call does, which is after all the arguments (and the function designator) have been evaluated. So they need to be evaluated for their side-effects before the abort is evaluated. The following testcase illustrates this; it should exit successfully but instead aborts. extern void exit (int); extern void abort (void); int foo (void) { exit (0); return 0; } void bar (void) { } int main (void) { ((long (*)(int))bar) (foo ()); abort (); } Much the same applies to va_arg, although the validity of the programs in this case is less clear (because the argument passed to va_arg isn't actually an object declared by the calling function). #include <stdarg.h> extern void exit (int); extern void abort (void); va_list ap; float f; va_list * foo (void) { exit (0); return ≈ } void bar (int i, ...) { va_start (ap, i); f = va_arg (*foo (), float); va_end (ap); } int main (void) { bar (1, 0); abort (); } -- Summary: generated aborts lose previous side-effects Product: gcc Version: 4.4.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: jsm28 at gcc dot gnu dot org OtherBugsDependingO 16620,16989 nThis: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38483