References
are pointers that are always initialized in their declarations to some existing
object, and cannot be re-assigned to point to other objects. They will always be
dereferenced when used, so their usage differs from pointers in their syntax.
The formal description of their usage is:
<type>
‘&’ <identifier> ‘=’ <object of the specified type> ;
Examples:
int a = 7;
int &ra = a;
ra++; // Now a
is 8. The integer is incremented, not the pointer
This
is a reference to an integer that is initialized to point to the address of the
integer ‘a’. Note that you should not specify the address-of operator, as
you would do with a normal pointer. It is the compiler that internally takes the
address of the resulting object.
· References cannot be re-assigned. Any re-assignment of a reference is a compilation error. The only exception is the initialization of a reference when it is declared or when the declaration includes an explicit external keyword.
· In an external reference, the type of the reference must be explicitly known to the compiler when the reference is first used, since to dereference an object (and references are always dereferenced when used) the compiler must know its definition.
· A function that expects a reference cannot receive a pointer. Pointers and references are not compatible and no automatic conversion between pointers and references is provided. To convert a reference to a pointer, use the address-of operator (‘&’).
· Tables of references are not possible.
· Pointer arithmetic is not possible with references.
· References of references are not possible.
· The initialization of a reference should always follow the declaration, unless the declaration is a function argument or a function result.
· Arrays of references are not possible.
· A reference cannot be assigned to a bit-field.
· The address of a reference cannot be taken, since the address-of operator will be applied to the object to which the reference points. In the example above, the expression &ra means the address of the object ra points to the integer a. The result will be the address of a and not the address of the reference.
· Since the address of a reference cannot be taken, there can be no pointers to references.
· In a function call to a function, which has a reference as argument in its prototype, the reference and not its value will be passed.
· In a function call to a function with no prototype or with one that does not have a reference in the given position, the value pointed to by the reference will be passed.
· In a return statement, when the function has a reference as return value, the compiler automatically takes the address of the resulting object, and returns this reference as the result of the function.
In
C++, passing arguments by reference avoids calling the automatic constructors
and destructors for the object. Since there are no destructors or constructors
called automatically here, the need for references is less pronounced. C is not
C++, and there are no functions being called ‘behind your back’ by the
compiler. All implicit function calls are those redefined explicitly by the
program.
Examples:
Given
int fn(int
&arg)
{
return
arg+8;
}
You cannot use:
fn(6);
for
instance. A constant is not automatically converted to a reference. This is
consistent with the C++ behavior.
[1]
This construct is needed by the problem of the operator [ ]. To avoid having
the construct Vector[5] = 6; be forced to be written as *Vector[5] = 5; or
add a new operator [ ]= incompatible with the C++ language, I decided to add
the references to lcc-win32. This has ancillary benefits because in general,
references are cleaner than pointers: you can do fewer things with them.
Since they always have to be initialized to a known object, there is less
room for error.
[2]
These rules are the same as in the C++ language.