I have encountered a working (with XLC8 and MSFT9 compilers) piece of code, containing a C++ file with a function defined with C linkage and a reference argument. This bugs me, as references are C++ only. The function in question is called from C code, where it is declared as taking a pointer argument to the same type in place of the reference argument.
Simplified example:
C++ file:
extern "C" void f(int &i)
{
i++;
}
C file:
void f(int *);
int main()
{
int a = 2;
f(&a);
printf("%d\n", a); /* Prints 3 */
}
Now, the word on the street is that most C++ compilers, under the hood, implement references just like a pointer. Is it like that and just pure luck the reason this code works or does it say somewhere in the C++ specification what the result is when you define a function with a reference argument and C linkage? I haven't been able to find any information on this.
A reference is an alternate name for an object. Technically, there is nothing in C that could map directly to a C++ reference.
The obvious implementation of a reference is as a (constant) pointer that is dereferenced each time it is used. So, depending on how your compiler implements references, your code might work. But it is not correct.
The solution is to write a C function that receives either a real object or a pointer to that object and call the C++ function from this.
That's what Bjarne Stroustrup has to say about references:
For example:
In this case, p needs not be stored in memory (maybe it just exists in a register, maybe it disappears into the instructions).
I think you already got some good answers so just pointing out something extra on your question.
My humble understanding is that extern merely creates a C symbol.
So your example still "seems to work" (gcc/g++) even when I add a class object - I had to try ir to believe it:
My copy of n3000.pdf (from here), has this to say in section 7.5—Linkage specifications:
Since C and C++ are different languages, this means that you can't rely on this "feature" of common compilers.
Stronger is note 5 in the same section (emphasis mine):
So, I would say that what you did is not guaranteed to work according to the standard, and the compiler is not required to print a diagnostic for the example you have given because the declarations are in different translation units.
FYI, it "works for me" with gcc and g++ version 4.2.1 on Snow Leopard.
In many cases, but not all, a reference can be implemented with an 'auto-dereferenced' pointer. That any particular compiler treats a function with C linkage and a reference parameter this way is not guaranteed in the C++ standard, and you should treat it as an implementation detail.
It isn't hard to write a forwarding function that takes a pointer and calls your function, if you need to do this without relying on implementation details: