Q:

How does 'pass variable by reference' work?

code like:
// 'type' here indicates certain variable type, int, char, struct, etc.
void foo(type &a, type b) {...}
type a = ...;
type b = ...;
type &c = a;
foo(a, b);
foo(c, b);

compiles with no problem. But literally the first parameter of foo is of type& which is a reference, and foo(c, b) looks more consistent to me than foo(a, b), because c is a reference type& itself but a only a type variable. 
For example say void bar(int*) and int *a; int b one can only pass a to bar not b due to different parameter type.
What's the underneath mechanism of such inconsistency in pass by reference case? 

A:

You're mixing up the declaration of a variable with its usage.
After:
type a = x;
type &c = a;

the situation is exactly the same as if you had written:
type c = x;
type &a = c;

In both cases there is one variable and it has two names, a and c.
Since C++11 there is one difference, decltype(a) will pick up the reference as part of the type
When you use a or c in an expression thereafter, it refers to that variable.
When you have void foo(type &p, type q)  (changed names to avoid confusion), then if you call foo(a, b);, then the name p becomes another name for the argument a. There is one object with two names, a (visible to caller) and p (visible in the function).
This latter case is usually implemented by compilers in the same way that passing by pointer is implemented (but implementation details are not something you should take into account when forming a mental model of what something means).

