0

On 86_64:

void x()
{
    void y(void);
    y();
}

disassembles to

x:
        jmp     y

whereas

void x()
{
    void y();
    y();
}

disassembles to

x:
        xorl    %eax, %eax
        jmp     y

IOW, why does eax need to be zeroed before making a prototypeless call?

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
  • What level of optimization did you specify? – Jonathan Leffler Jun 20 '17 at 15:59
  • 2
    Because without a prototype it may be a varargs function, and for those the sysv ABI requires `al` to contain number of SSE registers used (zero here). – Jester Jun 20 '17 at 15:59
  • @JonathanLeffler 3 of course :) https://godbolt.org/g/gseo2H – Petr Skocik Jun 20 '17 at 16:00
  • @Jester: that sounds plausible — but it's defensive. You can't legitimately call a varargs function without a proper prototype ending with ellipsis `int y(…, ...)` in scope, so `y` can't be a varargs. Officially. Funnier things have been known. – Jonathan Leffler Jun 20 '17 at 16:01
  • @Jester Thanks. I knew it was here somewhere. :) – Petr Skocik Jun 20 '17 at 16:05
  • I'll observe, slightly tongue-in-cheek, that I'd be happier if the functions were declared to return `void` since they don't return a value. – Jonathan Leffler Jun 20 '17 at 16:07
  • 1
    @Jester: Even if it is a varargs function, the compiler is not required to account for that. Calling varargs function without seeing a *prototype* has always been *undefined behavior* in standard C. C compiler is not required to accomodate for the fact that `fun` can potentially be varargs function. If some compiler does that, it is a peculiarity of specific implementation, not explainable in any way by rules of standard C language. – AnT stands with Russia Jun 20 '17 at 16:20

0 Answers0