Disadvantages of writing full code in header file and not use ".cpp" files?

Hi everyone, i know i'm doing it wrong but, as the title says, why can't i simply write the full code of my functions in an header files and put the header in the "main.cpp" without using any other ".cpp" files?
This is mainly for keeping the code organized.

Example:
MAIN: main.cpp
1
2
3
4
5
6
7
8
9
10
#include "MyFunctions.h"
int main
{
    int MyNumber;
    cout << "Insert the number to double.. ";
    cin << MyNumber << endl;

    DoubleTheNumber (MyNumber);
    return 0;
}


HEADER: MyFunctions.h
1
2
3
4
5
void DoubleTheNumber (int Number)
{
    Number = Number * 2;
    cout << Number << endl;
}
Last edited on
I don't see where you ever define a function called "DoubleTheNumber".
<edit: You updated your post to fix this>

That being said, if you naively put a function implementation in a header, and then #include in into more than one .cpp file, you'll get multiple definition errors. This can be avoided with the 'inline' keyword, which tells the compiler to not complain about multiple definitions (assumes the two (or more) definitions are the same).

The more stuff you put in a header, the more the compiler has to number crunch every time it compiles a file that uses that header. So you may get slower compilation times if you put everything in a header file.

Something something C++20 modules fix this something something.
Last edited on
you can do pretty much anything you like with small programs and a bit of understanding, and it WILL work FINE.
The problems caused by doing weird things show up in larger programs with lots of files.
So the answer is, for a small program typical of schoolwork, there isnt really a good reason to not do it however you like.

But the worst thing that can happen here is a small program that is useful, grown into a real commercial sized tool, will grow in size and number of files used. At some point, if you did it wrong, it will suddenly break and stop compiling at all, and fixing it can be a very challenging problem that can take a great deal of time and effort. And it hits out of the blue -- suddenly you need to do something different, and a minor change makes the whole house of cards fall apart.

I don't, most of us do not know how well modules will solve some of the issues you can create for yourself. Its new. But until those are well supported and working in all major compilers, your best bet is to do it right, and stick to what you were taught so that your program will work if you make it bigger, and you will have good habits as you get into the professional coding world. Note that some languages are much more strict than c++ and force you to follow THEIR WAY OR ELSE rules on source file names and contents. C++ is generous to a fault there; you can do it your way, but it will burn you eventually.

Another example of doing it wrong: you can include cpp files instead of header files, and it works, as long as you don't multiply define (as above explained). You can even include code snippets to force inline 'functions' if your compiler is being dumb (this is exceedingly rare these days; its a trick from decades ago when compilers were much less good). Such things are just bad ideas and best avoided entirely.
At the end of the day, realize what it is really DOING.
#include simply opens a text file, dumps the contents where the #include is located, and continues. Its a text substitution and little more(its recursive, of course, via includes having their own includes and so on). If dumping that wad of text in that spot is nonsense afterwards, the compiler chokes on it and you get a head scratcher to fix.
Last edited on
@LakySimi1, you have problems with your code other than header issues. You have int main, it's missing the parentheses.

You are using the iostream insertion operator<< to extract from std::cin. And including std::endl when getting input.

Do I need to point out your function defined in your header isn't the function you call in main?

Fix those errors, as well as including all the needed headers so your example code is SSCCE compliant, and try again.

http://sscce.org/

why can't i simply write the full code of my functions in an header files

You can if you only include your header file(s) in only one .cpp source file.

If you include headers in more than one source file then you have multiple function definition problems.

So really the idea you think of not separating interface (function declarations) from implementation is gonna bit ya in the butt big time as your code grows.

As Ganado says C++20 and modules somewhat overcomes this problem. If your compiler is capable of C++20 and use modules, great. Not every compiler is fully compliant yet. Visual Studio 2019/2022 are the only two currently.

Here's your code, rewritten for modules (VS 2022):
MyFunction.cppm (module interface file):
1
2
3
4
5
6
7
8
9
10
export module MyFunction;

import <iostream>;

export void DoubleTheNumber(int Number)
{
   Number *= 2;

   std::cout << Number << '\n';
}

main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
import <iostream>;

import MyFunction;

int main()
{
    int MyNumber;
    std::cout << "Insert the number to double.. ";
    std::cin >> MyNumber;

    DoubleTheNumber(MyNumber);
}
Insert the number to double.. 125
250
Last edited on
M'ok, you want to do headers, fine.

1. When writing headers you should include header guards, to prevent accidentally including multiple copies of the same code.
https://www.learncpp.com/cpp-tutorial/header-guards/

2. Function definitions can be done in a header file only, 1) if the function is declared as inline.
https://www.geeksforgeeks.org/inline-functions-cpp/

MyFunction.h
1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef MY_FUNCTION_H
#define MY_FUNCTION_H

#include <iostream>

inline void DoubleTheNumber(int Number)
{
   Number *= 2;

   std::cout << Number << '\n';
}

#endif 

main.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>

#include "MyFunction.h"

int main()
{
   int MyNumber;
   std::cout << "Insert the number to double.. ";
   std::cin >> MyNumber;

   DoubleTheNumber(MyNumber);
}
Same as above

Or, 2) as function templates.
https://www.learncpp.com/cpp-tutorial/function-templates/

It is still recommended to create separate header and source files for your own code. Doing so is recognized by C/C++ programmers as good code organization.

Inline functions can lead to code bloat because a copy of the machine code is inserted at every use of your function. The best inline functions are those that do very simple things.
Last edited on
I will read and reply to all of you soon.

For now: i adgusted the name of the function, and the code i provided is just an example of the concept in which i use only headers and no additional cpp files other than the main.cpp, the code isnot supposed to really work, it's just for exemplification. I'm sorry, maybe i should say that before.
Last edited on
LakySimi1 wrote:
the code isnot supposed to really work, it's just for exemplification. I'm sorry, maybe i should say that before.

That would have been helpful. :)

When writing psuedo-code it should still be syntactically correct. For example, using the insertion operator<< when you need the extraction operator>> is not a good idea.

Syntactically correct psuedo-code makes writing actual code that isn't buggy from language syntax errors much easier.
Also most compilers now support #pragma once at the start of a header file - rather than using code-guards with #ifndef/#define/#endif

1
2
3
4
5
6
7
8
#pragma once
#include <iostream>

inline void DoubleTheNumber(int Number)
{
   Number *= 2;
   std::cout << Number << '\n';
}


In addition, if you use templated-functions and header files, then the function has to be defined in the header file. It can't be declared in a header file with a .cpp file implementation. That gives a compilation error when the template is tried to be expanded. That's a reason why the standard library is a set of header files for all the code as the library is heavily templated.

Last edited on
I'm really sorry that i wasn't clear: i didn't ask help for the specific code, which is just for exemplification, i was asking WHY online i see headers with declaration and .cpp files with actual code, why are them separated??

I'n my raycasting engine (6000 unoptimized lines eheheh) i've never done this: one single cpp ("main.cpp") and 15ish header, each one for a specific purpose: movement, graphic, AI, etc.. and it works normally i would say, so why people divide declaration of a function and the code itself?

PS: if not clear please let me know! :) [english i not my first lenguage]
If all the code was written in header files you would have to recompile everything each time you made a small change that you wanted to test. This might not be an issue for a small project but it is for slightly larger projects that take minutes, sometimes hours, to compile from scratch.

By separating your code into header files you only need to recompile the .cpp files that have been modified or that include a header file that has been modified (indirect includes need to be considered as well).
Last edited on
Why are headers and implementation files generally created as separate files?

Does a user (programmer not you) really need to know how your function does what it does if they want to use the function? No.

All they want to know is "how to call the function"; what the parameters are, if any, and what the return type is.

There are exceptions to "The Rule" of course. Two examples have been pointed out. Inline and template functions.

6000 lines of code is rather a small(ish) amount, there are code projects that run into the hundreds of thousands, if not millions, lines of code.
Another advantage with .cpp files is that it can avoid some problems related to circular dependencies.

You could have A.cpp include B.h and B.cpp include A.h but if you were to put all the code into the headers you would run into problems because the code in A.h would need to include B.h in order to compile but B.h would need to include A.h in order to compile. This creates a circular dependency that cannot work.
seeplus wrote:
most compilers now support #pragma once at the start of a header file - rather than using code-guards with #ifndef/#define/#endif

Using #pragma once instead of header guards makes it um-possible to accidentally use the same macro name in multiple header files. That is a good feature.
headers can also help hide your secrets. If you sell a library for a living, you give out the header, so the user can see what the types are and some of the methods (the ones you want them to use) but the HOW is hidden in the cpp file which they don't get, they only get the compiled library and a .h file.

interestingly templates are all in the header, though. You will see that soon if you have not.


Thanky you eveyone, great forum!

So i would say it's mainly for readibility in larger project?

In fact it would be easier to have a "function menĂ¹" where click on and get to the actual function's code but i was too lazy to "copy paste" the function declaration twice ^^' (you know when starting learning something new and go fast like a train? eheh)
Let me give you an employer's view. If you were to not separate your .h and .cpp files, you would not last long as an employed programmer.
In fact it would be easier to have a "function menĂ¹" where click on and get to the actual function's code but i was too lazy to "copy paste" the function declaration

Aren't there magickal clickety clack GUI crap called "IDE" that do all menial chores -- except thinking?
If you were to not separate your .h and .cpp files, you would not last long as an employed programmer.


Shouldn't that sort of thing be defined in companies coding guidelines - along with other things like style of braces, format of variable names etc etc. Programmers then follow the guidelines for the company they happen to work for at the time - and need to be able to be flexible in coding 'style' to reflect/meet those guidelines.
So i would say it's mainly for readibility in larger project?

Its a mix. Partly for readability, partly because doing it any other way can lead to code that won't compile for various reasons.
one thing that would probably explode is 'circular' includes where you need a forward declaration to get it to work. eg a.cpp requires b.h but b.cpp requires a.h ... you can tie yourself in a knot trying to fix that if you don't know what to do; beginners get mindblown the first time they hit that kind of construct. I do not think it is even possible to do that all in the headers (not sure, maybe you can force it, but I would have to sit down and think on it and I probably won't because its not a generally accepted practice).

If you have only one source file that includes something, then you essentially have one 6000-line file for the compiler to process.

Build systems can compile multiple source files simultaneously, if you have more than one core in CPU. Surely compiling, say four 1500-line files is faster than compiling one 6000-liner (unless you really have a mono-core)?
Topic archived. No new replies allowed.