Should C++ Eliminate Header Files

Should C++ eliminate header files?

I routinely flip between C# and C++, and the lack of header files in C# is one of my biggest pet peeves. I can look at a header file and learn all I need to know about a class - what it's member functions are called, their calling syntax, etc - without having to wade through pages of the code that implements the class.

And yes, I know about partial classes and #regions, but it's not the same. Partial classes actually make the problem worse, because a class definition is spread across several files. As far as #regions go, they never seem to be expanded in the manner I'd like for what I'm doing at the moment, so I have to spend time expanding those little plus's until I get the view right.

Perhaps if Visual Studio's intellisense worked better for C++, I wouldn't have a compelling reason to have to refer to .h files so often, but even in VS2008, C++'s intellisense can't touch C#'s

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.

which one is right use of header file in C?

It is a good practice to mention #include lines in each module in a way that helps document that module. That way the next person to work on your code can look at it and see, for example, "aha, this module uses stdlib." It's a way of making your dependencies visible, both to compiler and to programmer.

So, if you use the capabilities of stdlib in your Destroy.c module mention it in an #include line. If you don't, leave it out.

If your main.c program uses the capabilities in your Destroy.c module, include Destroy.h in your main.c.

The same is true (in my opinion) when you decide whether to nest the #include of a system header file inside one of your header files. If the stuff in your header file itself makes use of the stuff in the system header file, include it.

This header-file pattern:

#ifndef MODULE_H
#define MODULE_H
/* lots of stuff */
#endif

has the purpose of making it possible to mention each header file where it's needed without worrying about including it more than once.

Another person suggested presenting your #include lines in a conventional order, with the system includes first. That is a good idea.

All of this is simply convention, rather than hard-and-fast rules. I'm offering a convention that has worked well for teams I have served on.

Edit Usually .c and .h files are paired. The .h file contains the declarations necessary to use the functions in the .c file. Sometimes that's just a function declaration, and sometimes it also includes declarations of constants, structs, and other such things. (I am writing about the C language here. In C++ class definition rules are clearer than in C.)

It is rare, but not impossible, that a header file you create will use stuff from a system header file. A case where it might: declaring a macro that does some kind of error logging.

Removing .h extension in user defined c++ header file

Can we remove .h extensions while we define our own header file in c++?

Sure, as long as that matches the filename of the file. As far as the language is concerned, the name of the file is largely irrelevant.

However, .h or similar such as .hpp is conventional, and helps the reader of the source to understand what the file is used for. This is an important consideration.

Another consideration is that some tools use the filename as a heuristic to determine the purpose of the file. For example, your IDE might not assume that the file contains C++ code, and thus not enable C++ features such as source analysis unless you follow a common naming convention.

I have created a header file and named it add.h and tried it including in source file using #include "add" but it didn't work.i know i am missing some important concepts here.

What you're missing is that the include directive must match the name of the file. If you include "add", then you must name the file add, not add.h. If you name a file add.h, then you must include "add.h", not "add".

Precompiled headers - necessary to remove all precompiled headers from all other files

The good practice is to make each file include all the headers directly required by this file. This way changing includes in particular file should effect only this file. If you start depending on headers included somewhere else it will make your project structure extremely fragile. And the single "common includes" file is an extreme case of such scenario. Use of precompiled header supposed to speedup compilation by prebuilding commonly included header files, but project files should never assume that something is already included there. So there is no need need to remove includes from ".h/.cpp", actually there are some tools that will populate precompiled header based on includes in project files. Compiler will skip files already included in precompiled header (or in other headers) because of header guards.

Is it a good practice to place C++ definitions in header files?

Your coworker is wrong, the common way is and always has been to put code in .cpp files (or whatever extension you like) and declarations in headers.

There is occasionally some merit to putting code in the header, this can allow more clever inlining by the compiler. But at the same time, it can destroy your compile times since all code has to be processed every time it is included by the compiler.

Finally, it is often annoying to have circular object relationships (sometimes desired) when all the code is the headers.

Bottom line, you were right, he is wrong.

EDIT: I have been thinking about your question. There is one case where what he says is true. templates. Many newer "modern" libraries such as boost make heavy use of templates and often are "header only." However, this should only be done when dealing with templates as it is the only way to do it when dealing with them.

EDIT: Some people would like a little more clarification, here's some thoughts on the downsides to writing "header only" code:

If you search around, you will see quite a lot of people trying to find a way to reduce compile times when dealing with boost. For example: How to reduce compilation times with Boost Asio, which is seeing a 14s compile of a single 1K file with boost included. 14s may not seem to be "exploding", but it is certainly a lot longer than typical and can add up quite quickly when dealing with a large project. Header only libraries do affect compile times in a quite measurable way. We just tolerate it because boost is so useful.

Additionally, there are many things which cannot be done in headers only (even boost has libraries you need to link to for certain parts such as threads, filesystem, etc). A Primary example is that you cannot have simple global objects in header only libs (unless you resort to the abomination that is a singleton) as you will run into multiple definition errors. NOTE: C++17's inline variables will make this particular example doable in the future.

As a final point, when using boost as an example of header only code, a huge detail often gets missed.

Boost is library, not user level code. so it doesn't change that often. In user code, if you put everything in headers, every little change will cause you to have to recompile the entire project. That's a monumental waste of time (and is not the case for libraries that don't change from compile to compile). When you split things between header/source and better yet, use forward declarations to reduce includes, you can save hours of recompiling when added up across a day.



Related Topics



Leave a reply



Submit