Search

2.11 — Header files

Headers, and their purpose

As programs grow larger (and make use of more files), it becomes increasingly tedious to have to forward declare every function you want to use that is defined in a different file. Wouldn’t it be nice if you could put all your forward declarations in one place and then import them when you need them?

C++ code files (with a .cpp extension) are not the only files commonly seen in C++ programs. The other type of file is called a header file. Header files usually have a .h extension, but you will occasionally see them with a .hpp extension or no extension at all. The primary purpose of a header file is to propagate declarations to code files.

Using standard library header files

Consider the following program:

This program prints “Hello, world!” to the console using std::cout. However, this program never provide a definition or declaration for std::cout, so how does the compiler know what std::cout is?

The answer is that std::cout has been forward declared in the “iostream” header file. When we #include <iostream>, we’re requesting that the preprocessor copy all of the content (including forward declarations for std::cout) from the file named “iostream” into the file doing the #include.

Key insight

When you #include a file, the content of the included file is inserted at the point of inclusion. This provides a useful way to pull in declarations from another file.

Consider what would happen if the iostream header did not exist. Wherever you used std::cout, you would have to manually type or copy in all of the declarations related to std::cout into the top of each file that used std::cout! This would require a lot of knowledge about how std::cout was implemented, and would be a ton of work. Even worse, if a function prototype changed, we’d have to go manually update all of the forward declarations. It’s much easier to just #include iostream!

When it comes to functions and objects, its worth keeping in mind that header files typically only contain function and object declarations, not function and object definitions (otherwise a violation of the one definition rule could result). std::cout is forward declared in the iostream header, but defined as part of the C++ standard library, which is automatically linked into your program during the linker phase.

Best practice

Header files should generally not contain function and variable definitions, so as not to violate the one definition rule. An exception is made for symbolic constants (which we cover in lesson 4.13 -- Const, constexpr, and symbolic constants).

Writing your own header files

Now let’s go back to the example we were discussing in a previous lesson. When we left off, we had two files, add.cpp and main.cpp, that looked like this:

add.cpp:

main.cpp:

(If you’re recreating this example from scratch, don’t forget to add add.cpp to your project so it gets compiled in).

In this example, we used a forward declaration so that the compiler will know what identifier add is when compiling main.cpp. As previously mentioned, manually adding forward declarations for every function you want to use that lives in another file can get tedious quickly.

Let’s write a header file to relieve us of this burden. Writing a header file is surprisingly easy, as header files only consist of two parts:

  1. A header guard, which we’ll discuss in more detail in the next lesson (2.12 -- Header guards).
  2. The actual content of the header file, which should be the forward declarations for all of the identifiers we want other files to be able to see.

Adding a header file to a project works analogously to adding a source file (covered in lesson 2.8 -- Programs with multiple code files). If using an IDE, go through the same steps and choose “Header” instead of “Source” when asked. If using the command line, just create a new file in your favorite editor.

Best practice

Use a .h suffix when naming your header files.

Header files are often paired with code files, with the header file providing forward declarations for the corresponding code file. Since our header file will contain a forward declaration for functions defined in add.cpp, we’ll call our new header file add.h.

Best practice

If a header file is paired with a code file (e.g. add.h with add.cpp), they should both have the same base name (add).

Here’s our completed header file:

add.h:

In order to use this header file in main.cpp, we have to #include it (using quotes, not angle brackets).

main.cpp:

add.cpp:

When the compiler compiles the #include "add.h" line, it copies the contents of add.h into the current file at that point. Because our add.h contains a forward declaration for function add, that forward declaration will be copied into main.cpp. The end result is a program that is functionally the same as the one where we manually added the forward declaration at the top of main.cpp.

Consequently, our program will compile and link correctly.

Best practice

A code file should #include its paired header file (if it exists). If you’re curious as to why, see nascardriver’s comment here.

Troubleshooting

If you get a compiler error indicating that add.h isn’t found, make sure the file is really named add.h. Depending on how you created and named it, it’s possible the file could have been named something like add (no extension) or add.h.txt or add.hpp. Also make sure it’s sitting in the same directory as the rest of your code files.

If you get a linker error about function add not being defined, make sure you’ve included add.cpp in your project so the definition for function add can be linked into the program.

Angled brackets vs quotes

You’re probably curious why we use angled brackets for iostream, and double quotes for add.h. The answer is that angled brackets are used to tell the preprocessor that we are including a header file that was included with the compiler, so it should look for that header file in the system directories. The double-quotes tell the preprocessor that this is a user-defined header file we are supplying, so it should look for that header file in the current directory containing our source code first. If it doesn’t find the header file there, it will check any other include paths that you’ve specified as part of your compiler/IDE settings. That failing, it will fall back to checking the system directories.

Rule

Use angled brackets to include header files that come with the compiler. Use double quotes to include any other header files.

Why doesn’t iostream have a .h extension?

Another commonly asked question is “why doesn’t iostream (or any of the other standard library header files) have a .h extension?”. The answer is that iostream.h is a different header file than iostream! To explain requires a short history lesson.

When C++ was first created, all of the files in the standard runtime library ended in a .h stuffix. Life was consistent, and it was good. The original version of cout and cin were declared in iostream.h. When the language was standardized by the ANSI committee, they decided to move all of the functionality in the standard library into the std namespace to help avoid naming conflicts with user-defined identifiers. However, this presented a problem: if they moved all the functionality into the std namespace, none of the old programs (that included iostream.h) would work any more!

To work around this issue, a new set of header files was introduced that use the same names but lack the .h extension. These new header files have all their functionality inside the std namespace. This way, older programs that include #include <iostream.h> do not need to be rewritten, and newer programs can #include <iostream>.

In addition, many of the libraries inherited from C that are still useful in C++ were given a c prefix (e.g. stdlib.h became cstdlib). The functionality from these libraries was also moved into the std namespace to help avoid naming collisions.

Best practice

When including a header file from the standard library, use the no extension version (without the .h) if it exists. User-defined headers should still use a .h extension.

Including header files from other directories

Another common question involves how to include header files from other directories.

One (bad) way to do this is to include a relative path to the header file you want to include as part of the #include line. For example:

While this will compile (assuming the files exist in those relative directories), the downside of this approach is that it requires you to reflect your directory structure in your code. If you ever update your directory structure, your code won’t work any more.

A better method is to tell your compiler or IDE that you have a bunch of header files in some other location, so that it will look there when it can’t find them in the current directory. This can generally be done by setting an include path or search directory in your IDE project settings.

For Visual Studio users

Right click on your project in the Solution Explorer, and choose Properties, then the VC++ Directories tab. From here, you will see a line called Include Directories. Add the directories you’d like the compiler to search for additional headers there.

For Code::Blocks users

In Code::Blocks, go to the Project menu and select Build Options, then the Search directories tab. Add the directories you’d like the compiler to search for additional headers there.

For GCC/G++ users

Using g++, you can use the -I option to specify an alternate include directory.

The nice thing about this approach is that if you ever change your directory structure, you only have to change a single compiler or IDE setting instead of every code file.

Headers may include other headers

It’s common that a header file will need a declaration or definition that lives in a different header file. Because of this, header files will often #include other header files.

When your code file #includes the first header file, you’ll also get any other header files that the first header file includes (and any header files those include, and so on). These additional header files are sometimes called “transitive includes”, as they’re included implicitly rather than explicitly.

The content of these transitive includes are available for use in your code file. However, you should not rely on the content of headers that are included transitively. The implementation of header files may change over time, or be different across different systems. If that happens, your code may only compile on certain systems, or may compile now but not in the future. This is easily avoided by explicitly including all of the header files the content of your code file requires.

Best practice

Each .cpp file should explicitly #include all of the header files it needs to compile. Do not rely on headers included from other headers.

Unfortunately, there is no easy way to detect when your code file is accidentally relying content of a header file that has been included by another header file.

Header file best practices

Here are a few more recommendations for creating and using header files.

  • Always include header guards (we’ll cover these next lesson).
  • Do not define variables and functions in header files (global constants are an exception -- we’ll cover these later)
  • Give your header files the same name as the source files they’re associated with (e.g. grades.h is paired with grades.cpp).
  • Each header file should have a specific job, and be as independent as possible. For example, you might put all your declarations related to functionality A in A.h and all your declarations related to functionality B in B.h. That way if you only care about A later, you can just include A.h and not get any of the stuff related to B.
  • Be mindful of which headers you need to explicitly include for the functionality that you are using in your code files
  • Every header you write should compile on its own (it should #include every dependency it needs)
  • Only #include what you need (don’t include everything just because you can).
  • Do not #include .cpp files.
  • Order your #includes as follow: your own user-defined headers first, then 3rd party library headers, then standard library headers. This is a minor one, but may help highlight a user-defined header file that doesn’t directly #include everything it needs.

2.12 -- Header guards
Index
2.10 -- Introduction to the preprocessor

500 comments to 2.11 — Header files

  • Bijit

    Can I know some other programs other than turbo c++ which I can use to run c++ programs on windows 7 ultimate ? You can send them on my email. Thank you sir.

  • Michael

    Hey Alex,

    I keep receiving the error "1>CPPTutorial.obj : error LNK2019: unresolved external symbol "int __cdecl add(int,int)" (?add@@YAHHH@Z) referenced in function _main"

    My files contain the same exact information as yours, and I'm confused why I'm getting this error. I'll post my code and see if you can help me out.

    main file:

    add.h:

    add.cpp:

    If anyone has any ideas why this might not work, let me know!

    Thanks,
    Michael

    • nascardriver

      Hi Michael!

      The code/files you posted are compiling fine for me, there must be something wrong with your project/compiler/linker settings.

    • Alex

      Most likely you forgot to add add.cpp to your project in your IDE, so add.cpp is not getting compiled.

      When you compile your project, do you see your compiler compile add.cpp? If not, that's the problem.

  • Cosmin

    Hey, Alex! I'm really enjoying the tutorials and I'm really grateful for all of the effort you put in. I want to ask you about where is the best to put a comment to WHAT my function does, in the header file or in the .cpp file?

    • nascardriver

      Hi Cosmin!

      Header: What does the function do? What are the parameters and return value?
      Source: How does the function do it?

    • Alex

      Great question. My take is that you should:
      * Document how to use the function (and what it does) in the header.
      * Document how the function works in the source code.

      General best practice is that users of a function should not need to look at the implementation at all (which isn't even possible if you decide to distribute your code as a precompiled library!)

  • yogesh brar

    Hi, first of all Happy New Year!
    I just wanted some clarification on the definitions thing. If header files just contains the declaration of the functions being used in the program; where are they defined?
    Like cin and cout these are declared in <iostream> header file but where are they defined, are they defined in the namespaces called std? and if so then do namespaces contains the definitions of the functions?

    • nascardriver

      Hi Yogesh Brar!
      Declarations are in header files (.h, .hpp), definitions are in source files (.cpp).
      Definitions could also be in header files, this will get you into trouble though.
      If a declaration is in a namespace then the definition must also be in the namespace, this doesn't affect the split into header and source!
      Functions you didn't write yourself (std::* eg.) come precompiled in a library so you don't need to compile them yourself. You cannot see the source code if libraries, only the header.

      • yogesh brar

        @Nascardriver thanks a ton for clarifying. This is so great to ask for any clarification about any topic on that page. Take Cares!

      • Dear nascardriver, please let me correct your snake.hpp file:

        Also let me comment that up to this lesson we have taught nothing about namespaces but std::, and nothing about function main's parameters. Regards.

    • Alex

      > If header files just contains the declaration of the functions being used in the program; where are they defined?

      Wherever you defined them. :) Typically, in a .cpp file of the same name, but it could be in any .cpp file. The linker should figure out how to connect everything.

      cin and cout are defined in the standard library, which is a precompiled library that gets linked into your program at link time. The std namespace does contain the definitions of the functions it contains. However, because it's provided in precompiled form, we can't see the source code containing the definitions.

  • Mark

    Hi,
    I have two questions please
    1- If I create a header file .h, do I need to create also a .cpp file?
    2- I made a simple program to apply what I'm reading, it is a program which only asks for the name and then outputs a world with the name entered.But when I try to open it from the application created by the debug build or the release build, the program do ask for the name and when I press enter the program doesn't last long maybe a portion of a second and it closes automatically. I want to know the reason please. The program compiles and links perfectly.
    Thank you.

    • nascardriver

      Hi Mark!

      No you don't, there are cases where you won't need a source file, because you don't have any source, just declarations. One such example are interfaces (Lesson 12.6). However, when you have source, use a source (.cpp) file.

      You can add

      to keep the console open until a key is pressed. More about std::cin in lesson 5.10

    • Alex

      1) No, you can have header files that have no corresponding .cpp file.
      2) Your OS is probably closing the output window when the program exits. See lesson 0.7 for a solution.

  • Jim

    Is it better if add.cpp also #include "add.hpp" ?

    • Alex

      It wouldn't hurt (outside of making your compile times marginally longer), but add.cpp doesn't do anything that requires it to see the declarations in add.h, so it's not necessary.

  • Monsieur Teacher,

    May I ask why in [#ifndef ADD_H] and [#define ADD_H] the [ADD_H] is capitalized? I don't see any reference to it and its never capitalized at any other point, and I did not capitalize mine and it ran ok. I just want to understand your reasoning.

    Thanks!

    • nascardriver

      Hi Dylan!
      I don't know which code style Alex is using or if he's just doing his thing, but it's common for include guards to be in all caps.
      Here are two style references that specify how include guards should be named:
      https://google.github.io/styleguide/cppguide.html#The__define_Guard
      https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#sf8-use-include-guards-for-all-h-files

      • Alex

        Yup, it's just common convention to use all caps for #defined values. It helps differentiate these values from other names (such as variable, function, or user-defined type names).

        The language doesn't require this though, so if you want to go against convention you can, you just may confuse other people who are wondering why you did something non-standard. :)

  • Hamed O.Khaled

    Hi Alex!
    Related to the section Why doesn’t iostream have a .h extension?
    is it mean that the .h version objects don't live in the std namespace but the non .h do , right ?
    cin -> iostream.h (doesn't live in std namespace)
    cin -> iostream (lives in std namespace)
    ?

    • Alex

      Yes, the .h headers were created before the standard library, so their contents aren't placed into the std:: namespace. When C++ moved the contents of the standard library to the std:: namespace, they created the headers without the .h extensions.

  • Trey

    I recently got a new computer and I'm testing out g++. Heres what my folder looks like:
        main.cpp
        src
            calc.cpp
            calc.h
    in main.cpp, I #include "calc.h" but it doesn't work, I tried g++ -o main -I /src main.cpp;  g++ -L/src/ main.cpp -o  main, but it still doesn't work

  • First I would like to thank you for this addictive awesome tutorial. I also would like to share what I got concerning this lesson, when adding a new .h file in Visual Studio, it starts with #pragma once, googling it, it said that this will allow the file to be included only once, I tried it instead the #ifndef #endif statement and it worked

  • Blessyn

    Dear Alex, I'm a newbie to C++ and Linux. There is this code I'm playing with that require me to install the HElib (Homomorphic encryption library and other libraries - GMP, NTL) which I did. I want to compile the code (main.cpp) that has a header file (FHE.h) in HElib. My problem is how can I link FHE.h (in HElib folder) and main.cpp (in another folder) together so that I can compile them. I have tried some commands
    [g++ -I/Home/HElib/src/FHE.h main.cpp -o main]
    Error message [main.cpp:1:17: fatal error: FHE.h: No such file or directory
    compilation terminated.]
    Another command line [g++ -I/Home/HElib/Src/FHE.h -I/Home/SimpleFHESum-master/SimpleFHESum-master/main.cpp -o main]
    Error Message
    [g++: fatal error: no input files
    compilation terminated.]

    Pls what shld I do?

    • Alex

      Try "g++ -L/Home/HElib/src/ main.cpp -o main"

      The -L flag should tell g++ where to look for header files when it can't find them in the default path.

  • Santosh Ujjwal

    Hi Alex! You said we could include header files from other directories by includind other paths in the Project Settings of out IDE. My doubt is: when we do that, do have to again add all the files containing the definitions of all the functions declared in these header files? Is that not a very tedious job that defeats our purpose in case of many user defined functions?

    • Alex

      If the header file has a corresponding code or library file, you'll need to make sure the code or library file is also added to your project.

      It is a bit tedious sometimes.

  • Julia

    Hi Alex! Thank you for your amazing tutorial. I have a problem though with using header files. I used you example with add.cpp and main.cpp. I tried to run it on terminal (on Mac, iTerm) with g++ main.cpp command (all files are in the same folder), but it gives me an error:

    Undefined symbols for architecture x86_64:
      "add(int, int)", referenced from:
          _main in ccMpPe8G.o
    ld: symbol(s) not found for architecture x86_64
    collect2: error: ld returned 1 exit status

    Tutorial says, make sure all the files are in the same project. So I tried it on Xcode, created a project with the same files and it works. Eh? So, I cannot run cpp-file containing headers on the terminal?

  • Really elaborate and clear in explanation. Bravo!

  • Razvan

    Hi! Great tutorial so far!

    I'm using Visual Studio 2017, and when I create a new header file it automatically adds

    on the first line. It seems I don't need to add anything except for the function prototype in this case and the program runs fine. Can you please add a comment about what

    does?

  • Vilius

    This is one great website, thank you so much!

  • Student C

    I created the following 'name.h' header file to print person's name and address.  However, when i included the header in my (.c) program, upon compiling, I received "identifier expected"?  What could be the issue?  The C book I'm using mentioned for this 'specific' exercise, not to put main(), preprocessor directives, or anything in the header file - but ONLY the three printf() functions calls in the code:

            printf("\n\n Jane Slater \n");
            printf("1605 N. 139th Street \n");
            printf("Miami, FL 20332 \n");

    In my main code,

    #include <name.h>

      main ()
      {
        printf("\n\n Jane's Header File Program: \n");
        return 0;
      }

    • Alex

      All three of those statements will be inserted at the point of the #include. Such statements are disallowed to be in the global scope (outside of functions) because the compiler wouldn't know when to execute them.

  • Oriel

    Hey Alex, how can I create a header file? Is it the same as creating and adding new .cpp files as mentioned in lesson 1.8?

  • Mahmud

    Hi Alex
    I understand that I have to use the #include <iostream> header file in order to be able to use "cout" and "cin". I am just trying to figure out what is the exact difference between the header file iostream and the namespace std. Is it like the std namespace is the name of a class inside the function declared in the iostream header file?

    • Alex

      The iostream header contains declarations for cout and cin, amongst others. Including iostream allows the compiler to understand what those are. Those identifiers live inside the std namespace, which is a namespace that is used to prevent naming conflicts (in case you'd defined your own identifiers named cout or cin).

      The std namespace isn't a class, it's a namespace. I cover namespaces in more detail in a future chapter (4 I think)

  • Bradon

    Hi Alex. Jluca013 said that he couldn't find out how to change the name of a file in visual studios but you didn't say how because he figured it out. However I have also encountered the same problem. I don't know how to change the name of, delete or change the project type of a file. Being a beginner I find my self making mistakes even in that field, but I don't know how to fix them. I would appreciate it if you would tell me how. Also I'm receiving the error: "Cannot open include file 'add.h': No such file or directory". I checked and double checked. My headers the same as yours (except the fact that I added "#include stdafx.h"). What is going wrong? is it what I named it because I did name it add.h but the IDE automatically changed it to add.h.cpp? As I mentioned before if the name or the format is the problem I don't know how to fix it. If you would answer that would be great. Thank you for this website, it is really helping me learn c++.

    • Alex

      These kinds of questions are hard to answer. If the compiler named your file add.h.cpp, then it's not named add.h, which is probably why it's complaining. If you're in the solution explorer window of visual studio, you can right click and choose rename to rename a file. If you're using some other IDE, I'm not sure how to help.

  • Ameen

    hello
    i am getting 3 errors when i create my own header file in code blocks
    i have included a separate path as you told by selecting project , build options....
    the errors are-
    invalid preprocessing directive #indef
    macro names must be identifiers
    invalid preprocessing directive #end

    and can you please tell me what is the meaning of macro here?

    thankyou

    • Alex

      #indef isn't a valid preprocessor command -- it should be #ifdef. Neither is #end -- it should be #endif.

      I talk about macros in the very next lesson.

  • jluca013

    I have a a naming issue with Visual Studio 2017. When I create my header file no naming window appears. The IDE defaults to "Header.h". I also do not see a way to rename the file when created. Have you encountered this issue before? Do you know of a solution?

    • jluca013

      I figured out that in order to create and use the header file correctly that it must be done from the "Solution Explorer" window. I am currently trying to understand why header files are useful if they only contain the declarations and not definitions. I am sure I alight will come on once I have contemplated this for a while.

      • Alex

        Header files primarily exist for a few reasons:
        * Propagate forward declarations to multiple files
        * Define types

        That's not something you'll do a lot of initially, but the farther you get into C++, the more often you'll do it. By the time you hit classes, creating multiple files becomes commonplace.

  • i want a small examples for
    Library function, uaerdefinefunction,fundamental function,complex function In c++?

  • Nameless

    I have a quick question. I am using VS 2017 when I am working with the header file I run into an issue with the use of "int" it gives me a
    "PCH WARRNING: Can't find a suitable stop location. a PCH file was not generated..."
    But when I add #pragma it removes this error all together and I had notice with your example you do not show the use of #pragma if you could possible explain the reason behind this error and the use of #pragma

    when I run with #pragma it doesn't run but removes this error I had stated above. If I had #include "stdafx.h" everything is fine... so I am a little unclear about this error I have tried googling but I still didn't really understand this.

    thanks in advance.

    P.S I have been looking for a website that best suits my needs of understanding and you give very clear and precise instructions thank you for this beautiful tutorial. Best C++ tutorial I have ever seen thank you Alex.

    • Alex

      Visual Studio uses precompiled headers by default. If you're using precompiled headers (and you are, unless you explicitly turn them off) then you should have #include "stdafx.h" as the first line of any code (non-header) file.

  • Sivasankar

    Hi Alex,

    Thanks a lot for your awesome tutorials.

    In "Can I put function definitions in a header file?" section, you said that there will not be any issue if function definitions are put in header file. Won't it cause linker errors if the same header file is included in multiple files (i.e. the same function is defined in multiple files)?

    • Alex

      Good point. I've updated the section to make it more clear that this will probably cause linker errors. I talk about why this happens in the upcoming chapter on header guards.

  • UV

    While i am compiling my add.cpp code i got the following message

    /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 0 has invalid symbol index 11
    /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 1 has invalid symbol index 12
    /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 2 has invalid symbol index 2
    /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 3 has invalid symbol index 2
    /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 4 has invalid symbol index 11
    /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 5 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 6 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 7 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 8 has invalid symbol index 12
    /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 9 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 10 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 11 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 12 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 13 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 14 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 15 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 16 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 17 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 18 has invalid symbol index 13
    /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 19 has invalid symbol index 21
    /usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_line): relocation 0 has invalid symbol index 2
    /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crt1.o: In function `_start':
    (.text+0x20): undefined reference to `main'
    collect2: error: ld returned 1 exit status

    • Alex

      This is the key error: /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crt1.o: In function `_start’: (.text+0x20): undefined reference to `main’

      Your program doesn't have a main() function. You need to create one.

  • AMG

    Many, many thanks for your time and efforts to explain C++ to the rest of the world. Amazing! In this chapter (1.9) identical names for add.h, add.cpp and function 'add()' may create a wrong pattern in naming files. For example, Kiril followed "add" naming style and used 'calc' to replace 'add' from your example. In other words, add.h -> myarithmetic.h, add.cpp-> myarithmetic.cpp. I think it would be better if file names would tell about content. Sorry, if my comment caused wasting your time.

  • Anshul

    Why we don't need to #include<iostream> in each source code file? add.cpp and main.cpp are compiled independently; to use cout functionality in add.cpp shouldn't we #include<iostream> here too?

    • Alex

      Yes, you should include iostream in any file that uses the functionality that iostream defines.

      In the example above, add.cpp does not use iostream, so including it is not necessary. If you decided to use std::cout in add.cpp, you'd need to include the iostream header in add.cpp.

  • mrlorin

    I'm really enjoying these tutorials, especially the Douglas Adams tribute?

Leave a Comment

Put all code inside code tags: [code]your code here[/code]