Question: I was discussing with a friend the following function prototype:

```
void str_buf_append(const char&);

```

The purpose is simply to add a character to a string buffer along with some other tasks irrelevant to the current question, which is: Given that we're not modifying the input character, is it better to pass by reference here or by value?

My friend's argument was that if you pass by reference for a char, you're putting onto the stack something with the size of an int whereas if you pass by value, you just put something on there that's only a byte in size.

In my opinion, though, that's not the whole picture: When you pass by value, I think you're actually doing the following:

1. Create a copy of the character at some location in memory distinct from that of the original character.
2. When the function is called, push onto the stack a reference to the copied character, thus not saving anything because under the hood, you're still using a pointer--just a pointer to a different memory location.

So my conclusion/opinion is that it is indeed more efficient to pass by reference than by value in this case.

Who is right?

Answer: 
The fact is that you can't predict what it will look like after optimizations take place; the only thing that stays "fixed" is the semantics of the code, not how it is actually executed.
This is a sketch of what happens at the line `fun (x);` when you pass by reference:

```
void fun (char const & c) {use (c);}
...
fun (x);
[next line]

```

1. Put return pointer to `[next line]` onto the stack at let's say memory address `A`. It's 4 or 8 bytes.
2. Put `p` which is a pointer to `x` onto the stack at let's say memory address `B`. It's 4 or 8 bytes.
3. When using `c`, its memory location is `[dereference [dereference B]]`.
4. Return to `[dereference A]`.

And here is what happens at the line `fun (x);` when you pass by value:

```
void fun (char const c) {use (c);}
...
fun (x);
[next line]

```

1. Put return pointer to `[next line]` onto the stack at let's say memory address `A`. It's 4 or 8 bytes.
2. Put `c` which is a copy of `x` onto the stack at let's say memory address `B`. It's 1 byte.
3. When using `c`, its memory location is `[dereference B]`.
4. Return to `[dereference A]`.

The addresses `A` and `B` (relative to the top of the stack) are hard-coded into the binary executable produced by the compiler.
The differences in steps 2 and 3 are size and single or double dereference, both in favor of passing by value.

That said, a modern compiler with optimizations turned on will probably optimize both programs above by inlining the function — if it is simple enough, producing the following:

1. ---
2. ---
3. When using `c` as parameter of `fun`, `x` is used instead.
4. ---