Search

1.7 — Forward declarations


Take a look at this seemingly innocent sample program called add.cpp:

You would expect this program to produce the result:

The sum of 3 and 4 is: 7

But in fact, it doesn’t compile at all! Visual Studio 2005 Express produces the following compile errors:

add.cpp(6) : error C3861: 'add': identifier not found
add.cpp(10) : error C2365: 'add' : redefinition; previous definition was 'formerly unknown identifier'

The reason this program doesn’t compile is because the compiler reads files sequentially. When the compiler reaches the function call to add() on line 6 of main(), it doesn’t know what add is, because we haven’t defined add() until line 10! That produces the first error (“identifier not found”).

When Visual Studio 2005 gets to the actual declaration of add() on line 10, it also complains about add being redefined. This is somewhat misleading, given that it wasn’t ever defined in the first place. Later versions of Visual Studio correctly omit this additional error message.

Despite the redundancy of the second error, it’s useful to note that it is fairly common for a single error to produce (often redundant) multiple compiler errors or warnings.

Rule: When addressing compile errors in your programs, always resolve the first error produced first.

To fix this problem, we need to address the fact that the compiler doesn’t know what add is. There are two common ways to address the issue.

Option 1: Reorder the function calls so add() is defined before main():

That way, by the time main() calls add(), the compiler will already know what add() is. Because this is such a simple program, this change is relatively easy to do. However, in a larger program, it can be tedious trying to figure out which functions call which other functions (and in what order) so they can be declared sequentially.

Furthermore, this option is not always possible. Let’s say we’re writing a program that has two functions A and B. If function A calls function B, and function B calls function A, then there’s no way to order the functions in a way that they will both be happy. If you define A first, the compiler will complain it doesn’t know what B is. If you define B first, the compiler will complain that it doesn’t know what A is.

Function prototypes and forward declarations of functions

Option 2: Use a forward declaration.

A forward declaration allows us to tell the compiler that a function exists before defining what the function does. This way, when the compiler encounters a call to the function, it’ll understand that we’re making a function call, and can check to ensure we’re calling the function correctly.

To write a forward declaration for a function, we use a declaration statement called a function prototype. The function prototype consists of the function’s return type, name, parameters, but no function body (the part between the curly braces). And because the function prototype is a statement, it ends with a semicolon.

Here’s a function prototype for the add() function:

Now, here’s our original program that didn’t compile, using a function prototype as a forward declaration for function add():

Now when the compiler reaches add() in main, it will know what add() looks like (a function that takes two integer parameters and returns an integer), and it won’t complain.

It is worth noting that function prototypes do not need to specify the names of the parameters. In the above code, you can also forward declare your function like this:

However, we prefer to name our parameters, because it allows you to understand what the function parameters are just by looking at the prototype. Otherwise, you’ll have to locate the actual function definition.

Tip: You can easily create function prototypes by using copy/paste on your function declaration. Don’t forget the semicolon on the end.

Forgetting the function body

One question many new programmers have is: what happens if we forward declare a function but do not define it?

The answer is: it depends. If a forward declaration is made, but the function is never called, the program will compile and run fine. However, if a forward declaration is made, the function is called, but the program never defines the function, the program will compile okay, but the linker will complain that it can’t resolve the function call.

Consider the following program:

In this program, we forward declare add(), and we call add(), but we never define add() anywhere. When we try and compile this program, Visual Studio 2005 Express produces the following message:

Compiling...
add.cpp
Linking...
add.obj : error LNK2001: unresolved external symbol "int __cdecl add(int,int)" (?add@@YAHHH@Z)
add.exe : fatal error LNK1120: 1 unresolved externals

As you can see, the program compiled okay, but it failed at the link stage because int add(int, int) was never defined.

Other types of forward declarations

Forward declarations are most often used with functions. However, forward declarations can also be used with other objects in C++, such as variables (which we discuss in section 4.2 — Global Variables. We’ll talk more about how to forward declare other types of objects in future lessons.

Quiz

1) What’s the difference between a function prototype and a forward declaration?

2) Write the function prototype for this function:

For each of the following programs, state whether they fail to compile, fail to link, or compile and link. If you are not sure, try compiling them!

3)

4)

5)

6)

Quiz Answers
1) Show Solution

2) Show Solution

3) Show Solution

4) Show Solution

5) Show Solution

6) Show Solution

1.8 — Programs with multiple files
Index
1.6 — Whitespace and basic formatting

59 comments to 1.7 — Forward declarations

  • GovZ

    Hello guys,

    You have a great tutorial here. Worthy of publication, IMHO.

    Anyways one question. Does Forward Declaration by function prototyping have an effect on the execution time or is this only used during the creation of some hash table or something? And that in the resulting executable, this step is not actually “re-read”.

    I hope I make sense. Thanks for your answers in advance. =)

  • GovZ,

    Forward declarations are used only to tell the compiler about the existence of a function (or class or variable) before it is actually implemented.

    This information is only used during compile time. Consequently, forward declarations will not make your executables larger or slower.

  • Dan

    Ahh, ok… I’m getting a clearer picture of this now (re: my question a few days ago in the previous ‘functions’ section
    when I asked about the order of functions in Cpp code). This helps explain the reasons why it must be. :)

    Thanks Alex!
    -Dan

  • Gary

    Hi there. I was wondering how come I have to type #include stdafx.h now. I haven’t used my compiler for a while, so I was just wondering. I can’t do this program unless I do it, but the Hello World one works just fine without it.

    By the way, in my older programs, the source files say “main.cpp” but the new one has 2 files, one that says stdfax.cpp and another one with the title of my project.

    I’m new to programming, so if my questions sound dumb, bear with me.

    • stdafx.cpp is a file that Microsoft compilers use to do precompiled headers (which makes you program compile faster), if you sent them up correctly. If you don’t want to deal with stdafx.h, you can always turn precompiled headers off (in the project settings).

  • Mitul

    /* I have writen one another Program like example 5*/

    #include <iostream.h>
    #include <conio.h>

    int add(int x, int y, int z);

    void main()
    {
    int x,y,z;
    clrscr();
    cout << "n Enter three number : n";
    cin >> x;
    cin >> y;
    cin >> z;
    cout << "n" << x << " + " << y << " + " << z << " = " << add(x, y, z) << endl;
    getch();
    }

    int add(int x, int y, int z)
    {
    return x + y + z;
    }

    • Doesn’t main have to be:

      not

      so that main returns a value?

      • Many (most?) compilers let you get away with using void main() instead of int main(), and they will implicitly return 0 when you do this. However, it’s not technically part of the language, so I avoid it in my examples.

    • ice

      I tried to run your program and came up with and error like this
      1>—— Build started: Project: 1, Configuration: Debug Win32 ——
      1> 1.cpp
      1>c:\users\marius\documents\visual studio 2010\projects\1\1\1.cpp(2): fatal error C1083: Cannot open include file: ‘iostream.h': No such file or directory
      ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

      • iLexy

        Since you use MSVS, you do not need to specify a library file, it takes care of that part for you so:

        #include <stdafx.h>
        #include <iostream>

  • This helped explain a lot of things I was previously having problems with.

  • jeff

    i am experimenting the code from the quiz number 6 and i try to changed the forward declaration variables
    from

    to

    after that i compiled the code by using microsoft visual studio 2008 and i notice that the code is successfuly compiled and the program is smoothly running.

    why is it that the compiler is not complaining while the forward declaration variable is different from the implementation?

    • Good question! It turns out that the variable names in your forward declarations don’t have to match those in the actual definitions. This is because the variable names in the forward declarations simply aren’t used — only the types are. You can even omit the variable names from the forward declaration altogether if you want.

      However, I think it’s generally good practice to put them in. If you see a forward declaration like this:

      It’s a lot less meaningful than if you see this:

  • adam

    So a function prototype is a kind of forward declaration?

    • It’s more accurate to say that one use of function prototypes is for forward declarations. Function prototypes can also be used in header files and in class declarations (covered in chapter 8). So function prototypes have more uses than just as forward declarations.

  • adam

    in solution one it says eturn instead of return

    [ Fixed! Thanks. -Alex ]

  • peddi

    Can we say the forward declaration in nothing but declaring the function globally, where as function prototyping is declaring function locally i.e, in the main function? is that only the difference? If then there is no way we can block the outsider from accessing our function which declared using forward declaration?

    • A forward declaration is a specific type of function prototype that allows you to declare a function before you actually define it. Unfortunately, there’s no way to “hide” such functions from “outsiders” — even if you don’t declare a function prototype, someone who wanted to use your function could write a function prototype for it and then use it.

      The only way to hide functions is to put them inside classes, which we’ll cover much later in this tutorial.

  • Julian

    I just found this site today after frustratingly leaving a different “learn C++” website, and I must say, your tutorials are a 100 times better than the other site I was on! :P

    It had about one paragraph on functions which was badly worded, and then went on to something about arrays and loops and binary trees and it had examples but they used functions in a way I didn’t even know was possible and it just confused the crackers outta me.

    I like the way these tutorials don’t teach everything about ‘functions’ in the one chapter, they teach the aspects of functions that would be easy to understand at this point, and then explain the more advanced features when the reader has a bit more knowledge about C++.

    Thankyou! :D

  • i m very weak in programing how can i improve it

    • Practice makes perfect! Pick a small project and figure out how to code it. Eg. a calculator, an address book, a little game, etc… You will learn as much from working on your own code and solving the problems you run into as you will from these tutorials.

      • csvan

        I double that. And triple it. I believe practical work is absolutely essential to building solid programming competence. You can learn all your life, but learning is in vain if it is only forgotten. Putting learnt knowledge into practice helps solidify it, and, I believe, can really contribute to it becoming a permanent part of your routine, not easily forgotten.

  • Justin

    Hi i have a question… i wrote my own code (same as yours but didn’t copy and paste) and i got a weird error that i do not under stand here is my code

    and this is the error message: 3 D:Dev-Cppmain.cpp expected `,’ or `;’ before ‘{‘ token

    Thankz
    Justin

  • Danny

    Y doesn’t it work? =/ can someone please help

    • Furious Sideburns

      I’ll have a crack at answering this (I’m new to all this myself). If I’m understanding this right, you’ve got a few syntax errors.

      You’re missing a ” at the end of your first #include

      should be

      Also, you need to lose the ; on the end of your forward declaration and your add function

      and

      should be

      and

      • csvan

        You almost got it, however you NEED to have a ; at the end of forware declarations, since they are statements. Thus, it is compleely correct to write:

        but not without the semicolon. C++ statements are ALWAYS concluded with semicolon (except for some structures, such as while and for loops).

        Also, you CANNOT write a parameters name as a number (for example int add(int 1);), that is not allowed by the compiler.

        Keep on coding. Use it for good. :)

    • csvan

      You have 3 errors here:

      1. The first line is missing a closing quotation mark (“) at the end (it should be “stdafx.h”).

      2. The second include statement does not include anything. I think you meant to include iostream, therefore it should read:

      3. The name of a parameter (or any variable as far as I know) can never start with a number, or simply be a number. Therefore, you will have to rename the parameters both in the function prototype and definition for add, for example like this:

      and make the same changes to the body of the function (change 1 to a etc).

      Keep coding. Use it for good.

  • Prayrit

    This is a weird concept to me, because every other language I’ve worked with(java, c#, actionscript) doesn’t care where the function is located…

  • Jon

    I don’t know if this was mentioned yet, on a brief scan I didn’t see it, so forgive me if you already answered this…
    You defined a function prototype as:

    A function prototype is a declaration of a function that includes the function’s name, parameters, and return type, but does not implement the function. In Question #2 on this page you give us:

    Did you mean us to solve for the forward declaration? If not, and you did mean to ask for the Function Prototype, shouldn’t you have given us only the Forward Declaration?

  • Florian

    Hi,
    i do have a problem understanding this:

    As the tutorial has stated earlier the program is running line by line so the function add would be unrecognized when it is called while add() is declared later on.

    On this example I would actually realize that we have created add() called it in main BUT we never reach the line where return x+y was written down.

    Basically I would expect a link error since the call ends up without returning anything?

    So my question is why does the program knows that add() returns the value x+y when it shouldn’t reach that declaration?

    Hope someone can understand this, i am German my English certainly lacks a bit.

    Thanks
    Florian

  • Florian

    Ok,

    I was thinking about it for a second, here is my explanation maybe someone can tell me if i am right.

    The program does work because c++ is compiled rather than interpreted. Which means as soon as we have created a prototyp the compiler gets through until the end and the compiled program has overwriten the first Prototype with the completed declaration (since the later declaration supersedes the first statement?

    Florian

    • Eugene

      Not quite. The prototype does not get overwritten. Rather, the forward declaration informs the compiler of how a call of that function should look like, and thus the compiler can do the necessary setup and translate the function call into assembly/machine code.

      The function definition defines the code that will be executed when the function is called. In this case it is in the same source file as the function call, but it could be in a different source file, or might not even be available at all, e.g., just the object code is available in a shared library.

      That said, some functions whose function definitions are available might be inlined, i.e., the function call is replaced by the code of the function itself.

  • Michael O.

    Hi Alex!

    Thanks a lot for these great tutorials, they’ve teached me a lot (I began 2 days ago).
    I agree with comment #1, these tutorials deserve a publication! I have tried to learn C++ some times before, but all the books I ended up with were hard to understand, the language was difficult, but these tutorials are very easy to understand, so again, thanks a lot Alex!

    -Michael O.

  • Jeno

    Hi,

    Thanks for this wonderful website!!!

    I wrote the following code, it compiles, links and executes well, but it seems like the Return Value is wrong:

    The output return value I get is -6, but when I compute the numbers myself it is a wrong calculation.

    What Am I missing?

    • Michael B

      Order of Operations.

      PEMDAS is it?

    • Ireul

      Sorry for disrespectful comment, but you miss grade school math classes.

      7 + 8 – 3 * 7 = 15 – 21 = -6, the answer given by output is perfectly correct.

    • Liquidcool

      Rule 1: First perform any calculations inside parentheses.
      Rule 2: Next perform all multiplications and divisions, working from left to right.
      Rule 3: Lastly, perform all additions and subtractions, working from left to right.

  • Its very great tutorial , it’s helpful and very good.
    thank you for putting together this wonderful lessons.

  • tcp

    okay so sometimes when i get to

    int add(int x, int y);
    {
    return x + y;
    }

    the little dropdown-menu-checkbox doesn’t appear. why is this? the little alert box to the left of the code is green, so it’s not registering as a problem, but it refuses to run the program unless int add is a dropdown item. (the code is perfect, the only difference between the site’s code and my own is the dropdown box).

    the error message:

    error C2447: ‘{‘ : missing function header (old-style formal list?)

    • Auge

      Lets have a look at your code:

      The semicolon after the function header must be dropped:

      The error message tells you that the compiler doesn’t recognize to which function the part within the curly brackets belongs to.
      That’s also because of the semicolon after the function header.

  • StelStav

    Hi all,

    I would like to ask what is the reasoning of c++ creators for forward declaration? Why isn’t the compiler designed in such a manner so as to look for a function definition regardless of it being before or after the actual function calling?
    I would imagine that it is enough that the function definition resided in the same scope of the function call.
    Would the above (my) logic effect the efficiency of the executable or just the compilation?

    Thanks in advance

    very nice site btw, good job admins :)

    • Alex

      C++ was developed a long time ago when computers were slow and memory was expensive. I suspect this limitation was done for efficiency/simplicity, so the compiler doesn’t have to parse the file more than once, or maintain memory-intensive lookup tables for all function calls.

      More modern languages (like C#) allow you to declare functions in any order without forward declarations. It’s unfortunate that C++ hasn’t added this.

  • That was exactly what i needed ! Thank you for your support ! =)

  • Anders Melen

    This tutorial is Perfect! Thank you so much for taking the time to help others learn a new great programming language! This could surly being published!, but thanks for making it available to all!

  • Steven

    Love the tutorials,
    It says to declare a function you don’t need to define it. Then in the definition for function prototype it’s a “declaration of a function that includes the function’s name, parameters, and return type”

    But when I try to compile

    It tells me add() can’t take 2 arguments, and forces me to declare

    at the beginning before it will compile/work. Wouldn’t that be a declaration WITH a function prototype? or should

    work at the beginning and I’m doing something wrong.

    • Alex

      Your forward declaration of add has no parameters, but your definition of add has two. There’s a mismatch there that’s causing the problem. Fix the forward declaration so it has two parameters.

  • donblas

    i know its been a while since this was used, but how do you make a program that does more than add a bunch of numbers?

  • misserwell

    Thank you very much, the article is so clear , hope more and more visitor knows the web

  • Da-Rage44

    I have a stupid question, what does it actually mean by the program never defines the function?

    Do we assume we need a return value to define a function?

    • If you only make a forward declaration and never actually make the function the program never actually makes the function, meaning you will get errors when you’re trying to use the forward declaration.
      No you don’t need a return value to declare a function (void), it just needs to be declared somewhere (it doesn’t even need to have code in it).

    • Alex

      > what does it actually mean by the program never defines the function?

      It means the program doesn’t define a function body (the part of the function between the curly braces).

  • fould12

    add.obj : error LNK2001: unresolved external symbol “int __cdecl add(int,int)” (?add@@YAHHH@Z)

    (?add@@YAHHH@Z) Makes me think of “add?…YAHHH!!”

  • Amjadb

    Can i just make a function call like : int add(int x, int y); before the line of add (3, 4) ?

Leave a Comment (Note: put C++ code inside [code][/code] brackets)

  

  

  

two − 2 =

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">