Why Should I Not Include Cpp Files and Instead Use a Header

Why should I not include cpp files and instead use a header?

To the best of my knowledge, the C++ standard knows no difference between header files and source files. As far as the language is concerned, any text file with legal code is the same as any other. However, although not illegal, including source files into your program will pretty much eliminate any advantages you would've got from separating your source files in the first place.

Essentially, what #include does is tell the preprocessor to take the entire file you've specified, and copy it into your active file before the compiler gets its hands on it. So when you include all the source files in your project together, there is fundamentally no difference between what you've done, and just making one huge source file without any separation at all.

"Oh, that's no big deal. If it runs, it's fine," I hear you cry. And in a sense, you'd be correct. But right now you're dealing with a tiny tiny little program, and a nice and relatively unencumbered CPU to compile it for you. You won't always be so lucky.

If you ever delve into the realms of serious computer programming, you'll be seeing projects with line counts that can reach millions, rather than dozens. That's a lot of lines. And if you try to compile one of these on a modern desktop computer, it can take a matter of hours instead of seconds.

"Oh no! That sounds horrible! However can I prevent this dire fate?!" Unfortunately, there's not much you can do about that. If it takes hours to compile, it takes hours to compile. But that only really matters the first time -- once you've compiled it once, there's no reason to compile it again.

Unless you change something.

Now, if you had two million lines of code merged together into one giant behemoth, and need to do a simple bug fix such as, say, x = y + 1, that means you have to compile all two million lines again in order to test this. And if you find out that you meant to do a x = y - 1 instead, then again, two million lines of compile are waiting for you. That's many hours of time wasted that could be better spent doing anything else.

"But I hate being unproductive! If only there was some way to compile distinct parts of my codebase individually, and somehow link them together afterwards!" An excellent idea, in theory. But what if your program needs to know what's going on in a different file? It's impossible to completely separate your codebase unless you want to run a bunch of tiny tiny .exe files instead.

"But surely it must be possible! Programming sounds like pure torture otherwise! What if I found some way to separate interface from implementation? Say by taking just enough information from these distinct code segments to identify them to the rest of the program, and putting them in some sort of header file instead? And that way, I can use the #include preprocessor directive to bring in only the information necessary to compile!"

Hmm. You might be on to something there. Let me know how that works out for you.

Is there a downside to including a cpp file over a header file? [duplicate]

We have header files for a reason. It (mostly) separates the interface of some code from its implementation. Some of the benefits include the compiler having to go through less code and not having to recompile every file that uses a function when you change its definition. Including source files can also violate ODR as pointed out in the comments.

Include .cpp instead of header(.h)

It's lazy coding. Use header files. Yes they can increase compile time but they mean that you can easily re-implement chunks of your code, or better yet, another developer could at anytime. The header file serves as a template for what your C/C++ code is going to do. It's a bad idea to discard or ignore it.

Why does C++ need a separate header file?

You seem to be asking about separating definitions from declarations, although there are other uses for header files.

The answer is that C++ doesn't "need" this. If you mark everything inline (which is automatic anyway for member functions defined in a class definition), then there is no need for the separation. You can just define everything in the header files.

The reasons you might want to separate are:

  1. To improve build times.
  2. To link against code without having the source for the definitions.
  3. To avoid marking everything "inline".

If your more general question is, "why isn't C++ identical to Java?", then I have to ask, "why are you writing C++ instead of Java?" ;-p

More seriously, though, the reason is that the C++ compiler can't just reach into another translation unit and figure out how to use its symbols, in the way that javac can and does. The header file is needed to declare to the compiler what it can expect to be available at link time.

So #include is a straight textual substitution. If you define everything in header files, the preprocessor ends up creating an enormous copy and paste of every source file in your project, and feeding that into the compiler. The fact that the C++ standard was ratified in 1998 has nothing to do with this, it's the fact that the compilation environment for C++ is based so closely on that of C.

Converting my comments to answer your follow-up question:

How does the compiler find the .cpp file with the code in it

It doesn't, at least not at the time it compiles the code that used the header file. The functions you're linking against don't even need to have been written yet, never mind the compiler knowing what .cpp file they'll be in. Everything the calling code needs to know at compile time is expressed in the function declaration. At link time you will provide a list of .o files, or static or dynamic libraries, and the header in effect is a promise that the definitions of the functions will be in there somewhere.

Why have header files and .cpp files?

Well, the main reason would be for separating the interface from the implementation. The header declares "what" a class (or whatever is being implemented) will do, while the cpp file defines "how" it will perform those features.

This reduces dependencies so that code that uses the header doesn't necessarily need to know all the details of the implementation and any other classes/headers needed only for that. This will reduce compilation times and also the amount of recompilation needed when something in the implementation changes.

It's not perfect, and you would usually resort to techniques like the Pimpl Idiom to properly separate interface and implementation, but it's a good start.

Any disadvantage if only using cpp files without separate header files?

In C and C++ the smallest unit of compilation is the file. If you just don't use header files and include everything in your "main" file, everytime you change something your whole program would have to be recompilled. For larger applications this can be a very good argument for separation of header and implementation. Also if another part of your application would live in another binary executable and you wan't to reuse classes you are safe with header files while you will get alot of overhead without them.

If you don't care about those things (You'll regret that.) there is no need in separate header files for you.

About the inlining: The compiler will inline a lot of functions (sometimes even whole classes, so to speak) anyway, even if you don't ask it to do that. Inlining is generally a benefit for performance. There are corner cases (large size of the executable can resolut in slower execution) but those are fairly unusual.

Why are .h files included in .cpp files and not vice versa? [duplicate]

This seems to be the right etiquette anyway.
It's not a matter of etiquette, but .cpp files are considered as translation units and handled as such by any decent compiler or build system.

The .h files contain all the declarations needed to be seen for use in other translation units.

The compiled .cpp files are stitched together in the final linking phase.

This way though, I'm not including the .cpp file anywhere, and currently my code is complaining about not finding the functions therein. What am I doing wrong?

You probably missed to get that last part of linking the generated object files right.

As for your edit:

You're showing a template declaration now, which is a more special case. The compiler needs to see the template definitions to get them instantiated correctly.

You can read more about the details here: Why can templates only be implemented in the header file?

Why do we include header files and not source files?

The moment you include Bob.h the compiler has everything it needs to know about PrintSomething(), it only need a declaration of the function. Frank.cpp does not need to know about Bob.cpp which defines PrintSomething().

All of your individual cpp files output object files generated by the compiler. These in themselves don't do much until they're all glued together, this is the linker's responsibility.

The linker takes all your object files and fills in the missing parts:

Linker talk:

Hey, I see that Frank.obj uses PrintSomething() and I can't see
its definition in that object file.

Let's check the other object files..

Upon inspecting Bob.obj I can see that this contains a usable
definition for PrintSomething(), let's use that.

This is of course simplified but that's what a linker does in short.

After this is done you get your usable executable.

on top of which if I were to now say in my Frank.cpp file: void MyClass::PrintSomething(){std::cout << "Bye";} and included the Bob.h
file in my main.cpp and called the PrintSomething() function would it
print "Hello" or "Bye"? Is the computer psychic or something?

The linker would find 2 definitions of PrintSomething() and would emit an error, it has no way to know what definition is the right one to pick.

Related Topics

Leave a reply