|
Type-safe linkage
There is an added benefit to all of this
name decoration. A particularly sticky problem in C occurs when the client
programmer misdeclares a
function, or, worse, a function
is called without declaring it first, and the compiler infers the function
declaration from the way it is called. Sometimes this function declaration is
correct, but when it isn’t, it can be a difficult bug to
find.
Because all functions must be
declared before they are used in C++, the opportunity for this problem to pop up
is greatly diminished. The C++ compiler refuses to declare a function
automatically for you, so it’s likely that you will include the
appropriate header file. However, if for some reason you still manage to
misdeclare a function, either by declaring by hand or including the wrong header
file (perhaps one that is out of date), the name decoration provides a safety
net that is often referred to as type-safe linkage.
Consider the following scenario. In one
file is the definition for a function:
//: C07:Def.cpp {O}
// Function definition
void f(int) {}
///:~
In the second file, the function is
misdeclared and then called:
//: C07:Use.cpp
//{L} Def
// Function misdeclaration
void f(char);
int main() {
//! f(1); // Causes a linker error
} ///:~
Even though you can see that the function
is actually f(int), the compiler doesn’t know this because it was
told – through an explicit declaration – that the function is
f(char). Thus, the compilation is successful. In
C, the linker would also be successful, but not
in C++. Because the compiler decorates the names, the definition becomes
something like f_int, whereas the use of the function is f_char.
When the linker tries to resolve the reference to f_char, it can only
find f_int, and it gives you an error message. This is type-safe linkage.
Although the problem doesn’t occur all that often, when it does it can be
incredibly difficult to find, especially in a large project. This is one of the
cases where you can easily find a difficult error in a C program simply by
running it through the C++
compiler.
|
|