In C++, code must be declared or defined before usage. For example, the following produces a compile time error:
int main()
{
foo(2); // error: foo is called, but has not yet been declared
}
void foo(int x) // this later definition is not known in main
{
}
There are two ways to resolve this: putting either the definition or declaration of foo()
before its usage in main()
. Here is one example:
void foo(int x) {} //Declare the foo function and body first
int main()
{
foo(2); // OK: foo is completely defined beforehand, so it can be called here.
}
However it is also possible to "forward-declare" the function by putting only a "prototype" declaration before its usage and then defining the function body later:
void foo(int); // Prototype declaration of foo, seen by main
// Must specify return type, name, and argument list types
int main()
{
foo(2); // OK: foo is known, called even though its body is not yet defined
}
void foo(int x) //Must match the prototype
{
// Define body of foo here
}
The prototype must specify the return type (void
), the name of the function (foo
), and the argument list variable types (int
), but the names of the arguments are NOT required.
One common way to integrate this into the organization of source files is to make a header file containing all of the prototype declarations:
// foo.h
void foo(int); // prototype declaration
and then provide the full definition elsewhere:
// foo.cpp --> foo.o
#include "foo.h" // foo's prototype declaration is "hidden" in here
void foo(int x) { } // foo's body definition
and then, once compiled, link the corresponding object file foo.o
into the compiled object file where it is used in the linking phase, main.o
:
// main.cpp --> main.o
#include "foo.h" // foo's prototype declaration is "hidden" in here
int main() { foo(2); } // foo is valid to call because its prototype declaration was beforehand.
// the prototype and body definitions of foo are linked through the object files
An “unresolved external symbol” error occurs when the function prototype and call exist, but the function body is not defined. These can be trickier to resolve as the compiler won't report the error until the final linking stage, and it doesn't know which line to jump to in the code to show the error.