Differences in the initialization of the EAX register when calling a function in C and C++

后端 未结 2 1415
悲哀的现实
悲哀的现实 2021-01-17 07:54

There is a curious difference between assemblies of a small program, when compiled as a C-program or as a C++-program (for Linux x86-64).

The code in question:

相关标签:
2条回答
  • 2021-01-17 08:25

    In C int fun(); can take any number of arguments, so it may even be a varargs function. In C++ however it means it takes no arguments.

    The x86-64 sysv abi convention demands that the register AL must contain the number of SSE registers used when invoking a varargs function. You of course pass no argument, so it is zeroed. For convenience the compiler decided to zero the whole eax. Declare your prototype as int fun(void); and the xor shall disappear.

    0 讨论(0)
  • 2021-01-17 08:26

    Apparently it is a defensive measure, designed for situations when prototype-less fun function happens to actually be a variadic function, as explained by @Jester's answer.

    Note though that this explanation does not hold any water from the point of view of standard C language.

    Since the beginning of standardized times (C89/90) C language explicitly required all variadic functions to be declared with prototype before the point of the call. Calling a non-prototyped variadic function triggers undefined behavior in standard C. So, formally, compilers do not have to accommodate the possibility of fun being variadic - if it is, the behavior would be undefined anyway.

    Moreover, as @John Bollinger noted in the comments, according to the C standard, a non-prototype int fun() declaration actually precludes further variadic prototype declarations of fun. I.e. a variadic function cannot be legally pre-declared as a () function. That would be another reason why the above non-prototype declaration is sufficient for the compiler to assume that fun cannot possibly be variadic.

    This could actually be a legacy feature, designed to support pre-standard C code, where pre-declaring variadic functions with prototype was not required.

    0 讨论(0)
提交回复
热议问题