[Question]
  [
Using your language of choice, write a function that takes a variable number of arguments and returns the number of arguments it was called with.
Specifics:
* Your language needs to support variadic argument functions: something callable that takes an arbitrary number of arguments and returns a value.
* Parameters must be able to be passed individually. This means that passing an array would only count for one parameter. You can use an "all passed arguments" array if your language supports it; the restriction is on how the function is called.
* Code that calls this function must not be required to pass the number of arguments *in its source*. If a compiler inserts the number of arguments as part of a calling convention, that is allowed.
* The arguments can be of any type you want. You can support only a single type (e.g. only supporting `int` is still valid), arbitrary types (any type of argument is allowed), or any combination of argument types (e.g. first arg is `int`, rest are strings).
* Your function may have a maximum number of arguments (especially since resources are finite), but must support *at least 2* arguments.
Samples:
* `f()` returns `0`
* `f(1)` or `f("a")` returns `1`
* `f([1, 2, 3])` returns `1` as it is passed an array, not 3 arguments
* `f(1, 10)` or `f(1, "a")` returns `2`
As this is code-golf, the winning solution is the one that uses the fewest number of bytes.
  
[Answer]
# [Java (JDK 10)](http://jdk.java.net/), 11 bytes
```
a->a.length
```
[Try it online!](https://tio.run/##jczBaoNAEAbgu0/xk5PCuCRp2qSEFPoAoQePJYdRd81aswnuKJTis9tFkmvtYRj4/5mv5p7Tuvwai4a9x5Gtw08EWCe6NVxovLeVn6IphIk/8loXopQCJ/uQD2FuXd7YAl5YwuqvtsQlUHEmrXXV5wkclOTOTKLBAdHI6RurRrtKzuN@KrNvL/qirp2oW/iVxsVGmThJ/qxXM/2CF3MCrZazJ/9hsCY8ETaEZ8ILYUvYEV4JD3@IhvEX "Java (JDK 10) – Try It Online")
[Answer]
# JavaScript, 15 bytes
```
[].push.bind(0)
```
The `Array.prototype.push` function takes any number of arguments, adds them to its array, and returns the size of the array. Therefore, the `push` function used on an empty array returns the number of arguments supplied to `push`.
```
f = [].push.bind(0)
f(10,2,65,7)
> 4
f()
> 0
```
The `.bind(0)` simply gives the `push` function a fixed `this` value so that it can be stored in a variable. In fact, the 7-byte identifier **`[].push`** can be used literally (but not assigned) without `bind`:
```
[].push(10,2,65,7)
> 4
[].push()
> 0
```
[Answer]
# JavaScript (ES6), 16 bytes
```
(...a)=>a.length
```
```
f=
(...a)=>a.length
console.log(f())
console.log(f(1))
console.log(f(1,2))
console.log(f(1,2,3))
console.log(f(1,2,3,4))
```
[Answer]
# [Haskell](https://www.haskell.org/), 108 107 95 94 bytes
```
class T r where z::Int->r
instance T Int where z=id
instance T r=>T(a->r)where z n _=z$n+1
z 0
```
[Try it online!](https://tio.run/##TYyxCoMwFEX3fsUdHBKkoGsg7t3dRMrDBnw0fciLIOTnYzoIrvecc1dK3xBjKUuklDBCcaxBA7JzL9mfgz5Y0k6yhArrcmHPnztRP4yGqm4vAYK3z420ffkRCzw25do3MCajs9gYHYzFNMO5/7UtJw "Haskell – Try It Online")
This was surprisingly hard to get working, but I had fun trying to find out how to implement something that's trivial in imperative languages.
[Answer]
## Amstrad CPC Z80 binary call from BASIC, 1 byte, hex encoded
```
C9          : RET
```
(Also 2 and 5 byte versions, see below)
Upon entry to the call, the number of parameters passed will be in the `A` register. The code simply returns immediately. There is no concept of return values in the Z80, just entry and exit states. The value is just "there" accessible in the register since the code changes no input conditions, except for `PC` (the program counter) and `SP` (the stack pointer). However, the value in `A` is not accessible to BASIC and gets overwritten almost immediately.
Examples:
```
CALL &8000, "Hello", "World"
```
`A` = 2
```
CALL &8000, 42
```
`A` = 1
```
CALL &8000
```
`A` = 0
---
By request, here is some code that makes the value accessible in BASIC. I was very surprised to find it could be done in only 5 bytes!:
### The machine code:
```
12          : LD   (DE), A
13          : INC  DE
AF          : XOR  A
12          : LD   (DE), A
C9          : RET
```
On entry:
* `AF` - the accumulator and flags registers (treated as two 8-bit registers)
	+ `A` contains the number of parameters passed, up to the maximum of 32 parameters
	+ I'm not sure what's in `F`. It appears to have all flags RESET to `0`, except the two undefined flags which are both `1`. The `Z` flag (zero) is SET to `1` if there were no parameters passed in
* `BC`
	+ `B` - 32 minus the number of parameters (`A` + `B` = 32)
	+ `C` - `&FF`
* `DE` - The address of the last parameter, or the calling address if no parameters were passed in
* `HL` - The address of the first byte after the tokenised BASIC command currently being executed (either as a program or in immediate command mode)
* `IX` - The stack address of the pointer to the last parameter
* `IY` - `&0000`
The code 
1. `L`oa`D`s the address pointed to by `DE` with the value in `A`
2. `INC`rements `DE`
3. `XOR`s `A` (with `A`), giving `&00`
4. `L`oa`D`s the value in `A` to the address pointed to by `DE`
5. `RET`urns
On exit:
* `A` is destroyed (it's always `&00`)
* `DE` is destroyed (it's always one higher than on entry)
* All other registers are preserved
### The BASIC
Amstrad basic has only three data types, plus simple arrays. By default, all BASIC variables are REAL (signed, 32 bit mantissa, 8 bit exponent), which can be made explicit with `!`. For an INTEGER (signed, 16 bit) use `%` and for a STRING (1 byte string length, up to 255 bytes character data, binary safe) use `$`:
* `x` - REAL (implicit)
* `x!` - REAL (explicit)
* `x%` - INTEGER
* `x$` - STRING
You can also use `DEFINT`, `DEFREAL` and `DEFSTR` with a single letter, or a range of two single letters to specify the default type for all variables starting with that letter, similar to FORTRAN.
* `DEFSTR a`
* `DEFINT x-z`
Now:
* `a` - STRING (implicit)
* `i` - REAL (implicit)
* `x` - INTEGER (implicit)
* `x$` - STRING (explicit)
The easiest type to work with is the integer. The machine code expects the last parameter to passed by address, not value, which is why `@` is prefixed to the variable. The return variable is counted as one of the `CALL`s parameters.
The machine code is called as follows from BASIC (assuming it's loaded at into memory at address `&8000`):
```
CALL &8000, "Hello", "World", 42, @n%
```
`n%` = 4
This will always give the correct result, regardless of the initial value of `n%`.
For a 2-byte version that preserves all input registers:
```
CALL &8003, "Hello", "World", 42, @n%
```
`n%` = 4
This skips the first three bytes, and only gives the correct result if the initial value of `n%` is `0`-`255`. This works because the Z80 is little-endian.
The return parameter must be initialised before being passed, otherwise BASIC will throw an `Improper argument` error. In the below image, I am printing (with the shortcut `?` since I've golfed the demonstration too!) the return values immediately before and after the call to show the value changing. I'm using the value `&FFFF` because that is the binary representation of `-1` for a signed integer. This demonstrates that the 5-byte program correctly writes both bytes, whereas the 2-byte program only writes the low byte and assumes that the high byte is already `&00`.
[![enter image description here](https://i.stack.imgur.com/Uc6TR.png)](https://i.stack.imgur.com/Uc6TR.png)
[Answer]
# [Python 3](https://docs.python.org/3/), 15 bytes
```
lambda*a:len(a)
```
[Try it online!](https://tio.run/##K6gsycjPM/6fZhvzPycxNyklUSvRKic1TyNR839BUWZeiUaahqYmF4xpiMRWSlRCltFRMDRA5WMoMNJRMNZRMNFRMNVRMNNRMNdRsNBRsIRo/A8A "Python 3 – Try It Online")
[Answer]
# [Zsh](https://www.zsh.org/), ~~7~~ 5 bytes
```
<<<$#
```
[Try it online!](https://tio.run/##qyrO@P/fxsZGRfn///9p@fn/kxKLAA "Zsh – Try It Online")
[Answer]
# [Brain-Flak](https://github.com/Flakheads/BrainHack), 6 bytes
My first Brain-Flak solution worthy posting, I guess it's the right tool for this job:
```
([]<>)
```
[Try it online!](https://tio.run/##SypKzMzLSEzO/v9fIzrWxk7z////hv91Df8bAAA "Brain-Flak (BrainHack) – Try It Online")
### Explanation
When executing a Brain-Flak program, initially the left stack contains all arguments. From there it's simply a matter of:
```
(      -- push the following..
 []    --   height of the stack (ie. # of arguments)
   <>  -- ..to the other stack  (toggles to the other stack)
)      --
       -- the right stack now contains the # of arguments which
       -- gets printed implicitly
```
[Answer]
# [Wolfram Language (Mathematica)](https://www.wolfram.com/wolframscript/), 11 bytes
```
Tr[1^{##}]&
```
[Try it online!](https://tio.run/##y00syUjNTSzJTE78n6Zgq/A/pCjaMK5aWbk2Vu1/QFFmXkl0WrSJjoKpjoKZjoJRbCwXTNBcR0HJRlc3USGvNDcptUgJxi0uASpIV0JSGZyZh8SLjf0PAA "Wolfram Language (Mathematica) – Try It Online")
Suggested by JungHwan Min. Some restrictions (input must be rectangular) but we are not required to handle arbitrary input.
**11 bytes**
```
Length@!##&
```
[Try it online!](https://tio.run/##y00syUjNTSzJTE78n6Zgq/DfJzUvvSTDQVFZWe1/QFFmXkl0WrSJjoKpjoKZjoJRbCwXTNBcR0HJRlc3USGvNDcptUgJxi0uASpIV0JSGZyZh8SLjf0PAA "Wolfram Language (Mathematica) – Try It Online")
Another 11 byte solution suggested by Martin Ender. This seems to error when there isn't one input but it still returns the correct value in all cases.
**12 bytes** 
```
Length@{##}&
```
[Try it online!](https://tio.run/##y00syUjNTSzJTE78n6Zgq/DfJzUvvSTDoVpZuVbtf0BRZl5JdFq0iY6CqY6CmY6CUWwsF0yw2thIx6BWR0HJRlc3USEns7hECcYpLgGqSVdCUhycmYfEi439DwA "Wolfram Language (Mathematica) – Try It Online")
My original solution.
In Mathematica `##` stands for a variadic number of arguments in a function. `{` and `}` wraps them in a list and `Length@` takes the length of this list. `&` at the end turns this into an actual function. 
[Answer]
# [R](https://www.r-project.org/), 30 bytes
```
function(...)length(list(...))
```
[Try it online!](https://tio.run/##K/qfZvs/rTQvuSQzP09DT09PMyc1L70kQyMns7gEzNf8n6ahyZWmYQgilBKVwGwdBUMDKAMhZKSjYKyjYKKjYKqjYKajYK6jYKGjYAlW@h8A "R – Try It Online")
[Answer]
# Bash, 12 bytes (thanks to paxdiablo for saving 4)
```
n()(echo $#)
```
Copy and paste at a bash prompt. Then run the n function from the prompt:
```
$ n
0
$ n 46 gr 3443 dad
4
$ n 4fwj23 wrw jdwj 00998 34 eyt q3 vg wq j qw
11
```
[Answer]
# [C++14 (gcc)](https://gcc.gnu.org/), 34 bytes
As generic variadic lambda function (C++14 required):
```
[](auto...p){return sizeof...(p);}
```
[Try it online!](https://tio.run/##jcq7DsIgGAXgnaf4U4dCgiRepkJ9EeOAXAxJC6TAYtNnR@uoQ53OyTmfinH/UKrunFdD0Ua4kPJk5HhBSJYcwEJfrze8dsZYJPNkcpk8JPc0wb4nHAlfKkfOZxil85jMCFLWXadCySAEWEzW@GzG64H//IdNQFvZbqMjbeRdNf/AEz1/s6W@AA "C++ (gcc) – Try It Online")
### Previous (incorrect) answer: 32 bytes
It was missing the `template<class...T>` and `(p)`
```
int f(T...p){return sizeof...p;}
```
[Answer]
# [Octave](https://www.gnu.org/software/octave/), 9 bytes
```
@()nargin
```
[Try it online!](https://tio.run/##y08uSSxL/Z9mq6en999BQzMvsSg9M@9/moaxjomOeklqcYm6jqUmV5oGCBvqGGr@BwA "Octave – Try It Online")
Anonymous function taking any number of arguments (and silently discarding the lot), and outputs the number of arguments through the built-in `nargin`. This does not work in MATLAB, where you would need `varargin` to allow for arbitrary many arguments.
[Answer]
# [Ruby](https://www.ruby-lang.org/), 12 bytes
```
->*a{a.size}
```
[Try it online!](https://tio.run/##KypNqvyfZvtf104rsTpRrzizKrX2f0FpSbFCWnQsF5RhCGcpJSohRHUUDA2QeWiSRjoKxjoKJjoKpjoKZjoK5joKFjoKlmBN/wE "Ruby – Try It Online")
`*a` is a splat of the arguments, making `a` consume all arguments passed to the Proc. `a.size` obtains its size.
[Answer]
# [Perl 6](https://github.com/nxadm/rakudo-pkg), 5 bytes
Thanks [@Joshua](https://codegolf.stackexchange.com/users/49934/joshua) for -5 bytes
```
{+@_}
```
[Try it online!](https://tio.run/##K0gtyjH7X1yapJD2v1rbIb72v3VBUWZeiUKahqGOgpGOgqXmfwA "Perl 6 – Try It Online")
[Answer]
# C++, 72 bytes
```
int f(){return 0;}template<class...P>int f(int,P...p){return f(p...)+1;}
```
Saves bytes by only working with ints.
[Answer]
# [Perl 5](https://www.perl.org/), 9 bytes
```
sub{~~@_}
```
[Try it online!](https://tio.run/##K0gtyjH9r5Jo@7@4NKm6rs4hvva/tYqOrVJMnpK1gnJAUWZeiUJ@XqpCQWqRQk5mXipXAViISyVR107DUMdIx1hTB8Ix1THTMdexgHGVEovSS3NT80oMlXTgbCMlTev/AA "Perl 5 – Try It Online")
[Answer]
# PHP, 34 bytes
```
function(...$a){return count($a);}
```
[Answer]
# C# .NET, 11 bytes
```
a=>a.Length
```
[Try it online.](https://tio.run/##ldJNawIxEAbgu7/ixdMuRK3aT8ReBE96aQ89iIdxd1ZT1kSSse0i/vZt/EKEottLYJJ3ngkkiW8k1nGZ5OQ9xpsakHLOcxKGNoJhtCJHSw87@@REJlNQ3AshLyQ6wRAZ@iip/0rNEZu5LEqgVzsHvqxOMSZtonhnA@@FF142B9Z4m3Pzw2nhkTYcZVG8l69G2hUydapXkVT7rlKsKtdRXXWvHtSjelLP6qUKf5s1/L17hsl0sx@wjau1nB5rc1EciMOCP04CjlYLA@tc2M4LOPbrXHy4ATr/GnvhvZ2VbliCQClshvYtMjp48ZWrksGMkekfTjErkJAXbeaQxe73rtZy7GuQc1RA7LEOk7e1bfkL)
**Explanation:**
In C# .NET `object` is used for multi-type arguments, allowing one to pass integers, strings, characters, etc. as possible inputs. For example:
```
// Can be called like: `F(2)`, `F("test")`, `F('a')`, etc.
void F(object arg){ ... }
```
C# .NET can also have a fixed size of optional arguments. For example:
```
// Can be called like: `F()`, `F(2)`, `F("test")`, `F('a')`, etc.
void F(object arg = null){ ... }
```
And there are also varargs, which is an undefined amount of optional arguments (which is what I've used in this answer). For example:
```
// Can be called like: `F()`, `F(2)`, `F(2, "test", 'a')`, etc.
void F(params object[] args){ ... }
```
Usually lambdas are created like this:
```
System.Func<object[], int> F f = a=>a.Length;
// A call like `f(new object[]{2, "test", 'a'))` will return 3 (size of the input array)
```
But unfortunately `System.Func` doesn't support `params` varargs, so I'll have to create a `delegate` instead:
```
delegate int F(params object[] args);
F f = a=>a.Length;
// A call like `f()` will return 0, and `f(2, "test", 'a')` will return 3
```
Which is my answer for this challenge, and can be found in the linked TIO test code.
---
The only limitation is that inputting an actual `object[]` like `f(new object[]{1,2,3})` will result in 3 instead of 1. `f(new int[]{1,2,3})` will still result in 1, because it interprets the `int[]` as a single `object`. To have the `object[]` parameter be interpret as a single object as well it can be casted to an object like this: `f((object)new object[]{1,2,3})`.
[Answer]
# [Dodos](https://github.com/DennisMitchell/dodos), ~~32~~ 31 bytes
```
f
	dot i f dab
i
	
	dip dot dab
```
[Try it online!](https://tio.run/##S8lPyS/@z5n2P42LMyW/RCFTIU0hJTGJK5OLEyiQWaAAEgQK/P//3/C/0X/L/4ZGxgA "Dodos – Try It Online")
Uses Dennis' increment function.
## Explanation
```
f                     # definition of f - target function
        dot i f dab   # sum of j(f(all args but first)). recurses until it has 0 args
i                     # definition of i - returns (arg, 1) given 1 arg
                      # arg
        dip dot dab   # 1 (dot dab on list of length 1 returns 0, dip returns |0 - 1|)
```
Alternatively, 32 bytes without recursion in target function (thanks [@Leo](https://codegolf.stackexchange.com/users/62393/leo))
```
	dot i
i
	dip dot dab dot
	i dab
```
[Try it online!](https://tio.run/##S8lPyS/@/58zJb9EIZMrk4szJbNAAcRJSUwC0VycmSDm////Df8b/bf8b2hkDAA "Dodos – Try It Online")
## Explanation
```
        dot i             # anonymous function: sum of i(args)
                          # here this becomes implicit main
i                         # definition of i - returns a list with all arguments replaced with 1
        dip dot dab dot   # 1 (dab dot returns empty list, dot returns 0, dip returns |0 - 1|
        i dab             # list concatenated with i(all args but first)
```
[Answer]
# Rust, 57 bytes
```
macro_rules!f{()=>{0};($($x:expr),+)=>{[$($x),+].len()};}
```
Explanation:
```
macro_rules! f {         // define a macro called f
    () => {0};           // when called without arguments, expand to 0
    ($($x:expr),+) => {  // when called with 1 or more comma seperated arguments
        [                // rust uses [a, b, c] to make an array
            $($x),+      // expand to the arguments seperated with a comma
        ]                
        .len()           // take the length of that.
    };
}
```
Test:
```
fn main() {
    println!("{:?}", f!());                // prints 0
    println!("{:?}", f!(4));               // prints 1
    println!("{:?}", f!(5, 2));            // prints 2
    // works with anything, as long as you dont mix things
    println!("{}", f!("", "a", "hello"));  // prints 3
}
```
[Answer]
# [R](https://www.r-project.org/), 20 bytes
```
function(...)nargs()
```
[Try it online!](https://tio.run/##K/qfZvs/rTQvuSQzP09DT09PMy@xKL1YQ/N/moahkbEOCJuYWpjrKKUpaXKlaeRkFpcAJXQMTTV1clJLSlKLinUUDK2AykCymv8B "R – Try It Online")
R has [a function just for that](https://stat.ethz.ch/R-manual/R-patched/library/base/html/nargs.html).
[Answer]
# PHP, 35 bytes
```
function(){return func_num_args();}
```
[manual entry](http://php.net/func_num_args)
[Answer]
# [Common Lisp](http://www.clisp.org/), 28 bytes
```
(defun f(&rest a)(length a))
```
[Try it online!](https://tio.run/##S87JLC74/18jJTWtNE8hTUOtKLW4RCFRUyMnNS@9JAPI0vyvUVCUmZesoJGmYKhgpGAJFAEA "Common Lisp – Try It Online")
[Answer]
# [Add++](https://github.com/cairdcoinheringaahing/AddPlusPlus), 3 bytes
```
L,L
```
[Try it online!](https://tio.run/##S0xJKSj4/99Hx@e/Sk5iblJKooKhHQgZ2SkYc/lzwQW5/P8DAA "Add++ – Try It Online")
[Answer]
# PHP, 11 bytes
```
<?=$argc-1;
```
Try it online: [1 input](https://tio.run/##K8go@P/fxt5WJbEoPVnX0Pr///@GAA) | [3 inputs](https://tio.run/##K8go@P/fxt5WJbEoPVnX0Pr///@G/43@GwMA)
[Answer]
# PowerShell 3, 25 bytes
```
function a(){$args.Count}
```
Usage:
```
a 1 2 ...
```
Console output for "a 1 2 3"
```
PS: C:\> a 1 2 3
3
```
Pretty self explanatory. Powershell stores all unspecified args in the $args list, so we just grab a count of it. Since the language implicitly writes values to the console, the act of finding the count will print to the console without needing a Write-Host or Write-Output.
Edit: Mistyped; should have been 25 bytes (typed 35).
[Answer]
## Batch, ~~50~~ 49 bytes
```
set n=0
for %%a in (%*)do set/an+=1
exit/b%n%
```
No builtin in Batch, so we have to go old-school. Saved 1 byte thanks to @IsmaelMiguel. Outputs via exit code, or save 3 bytes if output via global variable is valid. Example of use in a full program:
```
@echo off
call:c %*
echo %ERRORLEVEL%
exit/b
:c
set n=0
for %%a in (%*)do set/an+=1
exit/b%n%
```
[Answer]
# x86 32-bit (i386) machine code function, 13 bytes
Calling convention: **i386 System V (stack args), with a NULL pointer as a sentinel / terminator for the end-of-arg-list**. (Clobbers EDI, otherwise complies with SysV).
C (and asm) don't pass type info to variadic functions, so the OP's description of passing integers or arrays with no explicit type info could only be implemented in a convention that passed some kind of struct / class object (or pointers to such), not bare integers on the stack. So I decided to assume that all the args were non-NULL pointers, and the caller passes a NULL terminator.
**A NULL-terminated pointer list of args is actually used in C for functions like [POSIX `execl(3)`](http://man7.org/linux/man-pages/man3/exec.3.html)**: `int execl(const char *path, const char *arg, ... /* (char *) NULL */);`
C doesn't allow `int foo(...);` prototypes with no fixed arg, but `int foo();` means the same thing: args unspecified. (Unlike in C++ where it means `int foo(void)`). In any case, this is an asm answer. Coaxing a C compiler to call this function directly is interesting but not required.
`nasm -felf32 -l/dev/stdout arg-count.asm` with some comment lines removed.
```
24                       global argcount_pointer_loop
25                       argcount_pointer_loop:
26                               .entry:
28 00000000 31C0             xor   eax, eax  ; search pattern = NULL
29 00000002 99               cdq             ; counter = 0
30 00000003 89E7             mov   edi, esp
31                       ;    scasd           ; edi+=4; skip retaddr
32                       .scan_args:
33 00000005 42               inc   edx
34 00000006 AF               scasd            ; cmp eax,[edi] / edi+=4
35 00000007 75FC             jne  .scan_args
36                       ;    dec   edx       ; correct for overshoot: don't count terminator
37                       ;    xchg  eax,edx
38 00000009 8D42FE           lea   eax, [edx-2]    ; terminator + ret addr
40 0000000C C3               ret
size = 0D               db $ - .entry
```
The question shows that the function must be able to return 0, and I decided to follow that requirement by not including the terminating NULL pointer in the arg count. This does cost 1 byte, though. (For the 12-byte version, remove the LEA and uncomment the `scasd` outside the loop and the `xchg`, but not the `dec edx`. I used LEA because it costs the same as those other three instructions put together, but is more efficient, so the function is fewer uops.)
**C caller for testing**:
Built with:
```
nasm -felf32 -l /dev/stdout arg-count.asm | cut -b -28,$((28+12))- &&
 gcc -Wall -O3 -g -std=gnu11 -m32 -fcall-used-edi arg-count.c arg-count.o -o ac &&
 ./ac
```
[`-fcall-used-edi`](https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#index-fcall-used) is required even at -O0 to tell gcc to assume that functions clobber `edi` without saving/restoring it, because I used so many calls in one C statement (the `printf` call) that even `-O0` was using EDI. It appears to be safe for gcc's `main` to clobber EDI from its own caller (in CRT code), on Linux with glibc, but otherwise it's totally bogus to mix/match code compiled with different `-fcall-used-reg`. There's no `__attribute__` version of it to let us declare the asm functions with custom calling conventions different from the usual.
```
#include <stdio.h>
int argcount_rep_scas();       // not (...): ISO C requires at least one fixed arg
int argcount_pointer_loop();   // if you declare args at all
int argcount_loopne();
#define TEST(...) printf("count=%d = %d = %d   (scasd/jne) | (rep scas) | (scas/loopne)\n", \
        argcount_pointer_loop(__VA_ARGS__), argcount_rep_scas(__VA_ARGS__), \
        argcount_loopne(__VA_ARGS__))
int main(void) {
    TEST("abc", 0);
    TEST(1, 1, 1, 1, 1, 1, 1, 0);
    TEST(0);
}
```
Two other versions also came in at 13 bytes: this one based on `loopne` returns a value that's too high by 1.
```
45                       global argcount_loopne
46                       argcount_loopne:
47                           .entry:
49 00000010 31C0             xor   eax, eax  ; search pattern = NULL
50 00000012 31C9             xor   ecx, ecx  ; counter = 0
51 00000014 89E7             mov   edi, esp
52 00000016 AF               scasd           ; edi+=4; skip retaddr
53                       .scan_args:
54 00000017 AF               scasd
55 00000018 E0FD             loopne  .scan_args
56 0000001A 29C8             sub   eax, ecx
58 0000001C C3               ret
size = 0D = 13 bytes               db $ - .entry
```
This version uses rep scasd instead of a loop, but takes the arg count modulo 256. (Or capped at 256 if the upper bytes of `ecx` are 0 on entry!)
```
63                       ; return int8_t maybe?
64                       global argcount_rep_scas
65                       argcount_rep_scas:
66                               .entry:
67 00000020 31C0             xor   eax, eax
68                           ;    lea   ecx, [eax-1]
69 00000022 B1FF             mov   cl, -1
70 00000024 89E7             mov   edi, esp
71                       ;    scasd              ; skip retaddr
72 00000026 F2AF             repne scasd        ; ecx = -len - 2 (including retaddr)
73 00000028 B0FD             mov   al, -3
74 0000002A 28C8             sub   al, cl       ; eax = -3 +len + 2
75                       ;    dec   eax
76                       ;    dec   eax
77 0000002C C3               ret
size =  0D = 13 bytes         db $ - .entry
```
Amusingly, yet another version based on `inc eax` / `pop edx` / `test edx,edx` / `jnz` came in at 13 bytes. It's a callee-pops convention, which is never used by C implementations for variadic functions. (I popped the ret addr into ecx, and jmp ecx instead of ret. (Or push/ret to not break the return-address predictor stack).
[Answer]
# [Go](https://golang.org/), ~~44~~ ~~30~~ 28 bytes
-2 bytes thanks to BMO
My first code golf attempt.
```
func(a...int){print(len(a))}
```
[Try it online](https://tio.run/##S8//X5CYnJ2YnqqQm5iZx5VWmpcMZmloVnMplCUWKaQp2P4HiWok6unpZeaVaFYXFAEpjZzUPI1ETc3a/2kahjpGOsY6BprWXLX/AQ) (outputs to Debug-window instead of STDOUT).
]