Visibility of function prototypes and declarations
suggest changeIn C++, code must be declared or defined before usage. For example, the following produces a compile time error:
int main()
{
// error: foo is called, but has not yet been declared
foo(2);
}
// this definition is not known in main
void foo(int x)
{
}
main.cc: In function 'int main()':
main.cc:4:5: error: 'foo' was not declared in this scope
4 | foo(2);
| ^~~
exit status 1
There are two ways to resolve this: putting either the definition or declaration of foo()
before its usage in main()
. Here is one example:
// declare 'foo' function first
void foo(int x) {}
int main()
{
// OK: 'foo' has been defined, so it can be called here.
foo(2);
}
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:
#include <cstdio>
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
}
// Must match the prototype
void foo(int x)
{
std::printf("foo() was called\n");
}
foo() was called
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.