0

It has been my understanding that C variadic arguments are handled entirely on the callee's side, i.e. that if you called a function f with

f(1, 2, 3.0)

The compiler would generate the same code for the call, whether you had declared f as

void f(int, int, double);

or

void f(int, int, ...);

The context for this question is this issue with calling a not-truly-variadic C function from Rust with a variadic FFI definition. If variadics do not matter from the caller's perspective (aside of course from type checking), then it seems odd to me that Rust would generate different code for a call where the function had been declared as variadic.

If this is not in fact decided by the C specification, but rather ABI-dependant, I would be most interested in the answer for the System V ABI, which from what I read of it didn't seem to indicate any special handling of variadics on the caller's side.

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
lcmylin
  • 2,552
  • 2
  • 19
  • 31

1 Answers1

2

This is a non-ABI-specific answer.

Yes, formally the caller can (and, in general case, will) treat functions with variadic arguments in a special way. This is actually the reason why from the beginning of standardized times C language required all variadic functions to be declared with prototype before the point of the call. Note that even though it was possible to safely call undeclared functions in C89/90, the permission to do so did not extend to variadic functions: those always had to be declared in advance. Otherwise, the behavior was undefined.

In a slightly different form the rule still stands in modern C. Even though post-C99 C no longer allows calling undeclared functions, it still does not require prototype declarations. Yet, variadic functions have to be declared with prototype before the point of the call. The rationale is the same: the caller has to know that it is calling a variadic function and, possibly, handle the call differently.

And historically, there were implementations that used completely differrent calling conventions when calling variadic functions.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • Note also that variadic arguments are subject to type promotions that are not necessarily the same as would be performed in the presence of a non-variadic prototype. – John Bollinger Feb 01 '17 at 19:29
  • @JohnBollinger: Which is likely the actual reason for requiring the declaration, noit the potentially different ABI. AAPCS for instance uses the same convention as for fixed-parameterlist functions. – too honest for this site Feb 01 '17 at 19:32
  • @Olaf: But these promotions are identical to the ones that would be performed in context of calling a function with *non-prototype declaration* or (in case of C89/90) with no declaration in sight at all. Which immediately means that no, this is not the actual reason for requiring a *prototype*. – AnT stands with Russia Feb 01 '17 at 20:02