https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118831
--- Comment #11 from Jakub Jelinek <jakub at gcc dot gnu.org> --- It is still invalid even if you are lucky and it doesn't crash. And it easily can crash at least with older gcc versions. E.g. with #include <stdarg.h> int foo (int a, ...) { va_list ap; va_start (ap, a); if (a == 42) a = va_arg (ap, double); va_end (ap); return a; } until GCC 4.5 on x86_64 this emitted an indirect jump based on %rax value upon entry, so if it is garbage from the caller, if you are lucky and it is 0-8, it will seem to work, if it is above that, the code will just crash. GCC 4.6 changed it so that the compiler at least when optimizing tracks if some floating point (or some integer) va_arg is ever used and how many and only uses if (rax) save_the_needed_xmm_regs; but it is still undefined behavior then. In C you can't in another TU do int foo (); void bar (void) { foo (1, 2, 3); } either, it is UB as well.