0

This web page says:

C supports variable numbers of arguments.

Okay, I got that.

But there is no language provided way for finding out total number of arguments passed.

Really? Is that true?

Apparently it is true because in every example that I have seen of a function with a variable number of arguments, there is always an argument that specifies the number of arguments, e.g.,

int sum(int numargs, ...)

Isn't that cheating?

Isn't the whole point of a function with a variable number of arguments is for the function to figure out how many arguments are provided? (Not be told how many arguments are provided)

Is there no way to create a function that sums an arbitrary number of integers, without the caller telling the function how many integers there are? (And without forcing the caller to append some sort of sentinel value like NULL onto the end of their argument list)

Is this possible:

int sum(...)
Roger Costello
  • 3,007
  • 1
  • 22
  • 43
  • 4
    Yes, it's really true. But I'm not sure what kind of answer would be useful to you. I can answer your questions one by one (yes it's true, no there is no way to sum an arbitrary number of integers, etc), but the only supporting evidence I can give is "read the entire C standard and you won't find any provision that makes this possible". – Nate Eldredge May 29 '21 at 17:21
  • you can't get that in C, but it's possible with some helper macros. Duplicates: [How to count the number of arguments passed to a function that accepts a variable number of arguments?](https://stackoverflow.com/q/4421681/995714), [number of passed arguments in a va_list](https://stackoverflow.com/q/15198033/995714), [Is it possible to validate a variable argument count?](https://stackoverflow.com/q/64110666/995714) – phuclv May 29 '21 at 17:23
  • 1
    I think that is just how C works. It doesn't do anything for you. You have to do that yourself. – Yoshikage Kira May 29 '21 at 17:23
  • 1
    I think instead of using `...` you can just use an array. – Yoshikage Kira May 29 '21 at 17:25
  • [Macro to count number of arguments](https://stackoverflow.com/q/11317474/995714), [Count number of variadic arguments in macro function](https://stackoverflow.com/q/53847219/995714), [Count number of parameters in C variable argument method call](https://stackoverflow.com/q/3868289/995714) – phuclv May 29 '21 at 17:25
  • 1
    @Goion - arrays don't have length information embedded in them. – selbie May 29 '21 at 17:25
  • @Goion easy for the caller, impossible for the callee. – Cheatah May 29 '21 at 17:29
  • @Goion Not sure if is is meant to be a joke, but you seem to be thinking of some other language, C arrays do not have methods, there is no `array.size()` in C – Lev M. May 29 '21 at 17:29
  • @Lev M. I don't remember the syntax on top of my head. I meant `sizeof(array)/sizeof(array[0]);`. But I remember this wouldn't work when array is passed as argument since the pointer will be passed. That slipped my mind altogether. – Yoshikage Kira May 29 '21 at 17:36
  • @Goion - That won't work like you think it will. At least not when pass `array` is passed as a function parameter. If you implement a `sum` function that can take an integer array of an arbitrary number of elements, you will not only have answered the OP's question, but you will win a Turing award. – selbie May 29 '21 at 17:38
  • 2
    There is no way to know the number of arguments, or the type of the arguments. How would the number of arguments be useful if you don't even know the types? C is a simple language. If you want those features, you can use C++ variadic templates. – Aykhan Hagverdili May 29 '21 at 17:39
  • @selbie Yes I realized it a little late. I kinda wonder how argc argv works behind the scene. – Yoshikage Kira May 29 '21 at 17:40
  • To close: Parameter arguments to a function are simply pushed onto the program stack and popped off by the code behind the invoked function. The "count" of stack arguments isn't conveyed by this state. Hence, to fix this, it would require a language extension that wouldn't be backwards compatible with existing (compiled) code. And since everyone agrees that the workaround (adding a count hint or format specifier) as an additional parameter isn't a burden, it probably won't get fixed anytime soon. – selbie May 29 '21 at 17:43
  • @Goion `main` isn't variadic. It has an unspecified number of arguments which is a different thing. It's like when you declare a function like `int func()` in C and after that you can call it with any number of arguments like `func()`, `func(1, 2, 3, 4)`... See [C: Unspecified number of parameters - void foo()](https://stackoverflow.com/q/22073893/995714). There are some standard functions like that such as `open` where you can call it as `open(filename, O_RDONLY);` or `open(filename, O_CREAT | O_WRONLY, 0777)` https://devblogs.microsoft.com/oldnewthing/20160623-00/?p=93735 – phuclv May 30 '21 at 02:01

1 Answers1

2

To really understand why this is true, and why there can only be workarounds like providing sentinel value or format string (like printf does), you need to look at how C functions are compiled.

https://en.wikipedia.org/wiki/X86_calling_conventions

If you look at the assembly that is generated (try gcc -S if you are on a *nix type OS), you will see there is no information regarding how many arguments are being passed, and it is up to the code of the function to pull them off the stack (usually, some conventions pass some arguments via registers).

As a matter of fact, not only the count, but the type information is lost in compilation as well.

Unlike other, newer languages, all C function has to access parameters is a stack pointer, from there it is up to the function to decide what to pop off the stack and how to interpret it.

The variadic syntax in C just allows you to bypass the rigid argument checks during compilation, and give back some of the assembly level freedom regarding function arguments.

Lev M.
  • 6,088
  • 1
  • 10
  • 23