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;
}
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.
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.
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>;
exportvoid 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);
}
#ifndef MY_FUNCTION_H
#define MY_FUNCTION_H
#include <iostream>
inlinevoid 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);
}
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.
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.
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>
inlinevoid 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.
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).
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.
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.
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)
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)?