Your function has four parameters.
Each parameter must be passed to the function.
The fact that one of the parameters is a reference does not change this basic fact. The additional space you see is the reference parameter to the function.
In this context, the reference is really just a pointer in disguise. When you have a reference in a local scope referencing to an object in the local scope, most C++ compilers will, indeed, optimize it away so that the reference does not take up any actual memory.
But a function call is an entirely new ball game. The function expects to receive a reference to some object. The function cannot know telepathically what is being passed to it as a reference. Whatever is calling the function is responsible for supplying the reference parameter. It goes without saying that a few bytes will be needed to pass along that information, namely the address of an object that's passed as a reference (did I mention something about pointers, recently?)
It is certainly possible that if the function was declared with static
scope (no external linkage), and a sufficiently aggressive optimization level is selected for compilation, your C++ compiler will inline the function call, and be able to optimize the reference parameter away.
But declaring a function with external linkage generally results in the compiler not bothering to attempt to inline the function call. It will proceed and generate a full-blown, standalone function, that expects to have each and every parameter it is entitled to.
To answer your question in a more general way: the C++ standard does not require that references should occupy memory, but it does not require that they should not. The C++ compiler is free to compile the code in any way, as long as the results are correct, and what they are expected to be. If, in a particular situation, a C++ compiler figures out how to optimize away a reference so that it does not actually "exist" as a discrete object of its own, it is free to do so. But it is not required to do that.