Why the definition of functions are separated from declarations? - c++

Why the definition of functions is not written in the same "some.h" file together with their declarations? What will be happen if we are not separate "some.h" file from "some.c" file?

So that one knows the minimum he needs to know. (This makes the compilation faster, chances of name collisions lesser, ability to manage code easier etc) As mentioned in this comment by Kerrek SB: If you mix source and code, dividing big projects into modules is difficult.
For example, you can compile a library (Containing definition) and give it to your clients (who care only about the interface) along with the declarations (Headers) and he would be able to use it without needing to know the source of implementation. (This way you can also hide the implementation detail)
Without headers, he doesn't know usage of functions available in library. So though not mandatory, it is recommended to keep the declaration and definitions separate.

Well in fact, separating declarations and definitions is not mandatory, while in practice everything was thought this way to separate usage and implementation, this to promote abstraction, reusability, modularity, etc.
If you don't follow these rules then you will very rapidly face compilation problems with multiple definitions, etc.

Related

A tool to make the division of C++ code into .h and .cpp files transparent to the programmer

C++ was the the first language I've learnt so dividing source code into .h and .cpp files seemed obvious - but having learnt C# and Java they now appear to me terribly clumsy. They might have been useful back in the 60s, maybe still even in 80s, but in the era of modern tools, such as IDEs with section folding, and documentation generators, they seem obsolete.
Anyway, my question is: is there a tool which makes the presence of these two kind of files transparent to the programmer? For example by letting the coder write the definition of a method seemingly in the header file but actually saving it to the .cpp file?
(I know one can try to write a C++ program solely in header files but AFAIK this is not considered best practice, makes the program build even longer and makes it virtually impossible for two classes to reference each other.)
The discussion that I am seeing in the question, comments and the comments to the other answer seem to focus on the textual representation of the components. From the point of view of plain text, it makes sense to remove the headers altogether.
On the other hand, there is a second level to the separation of headers and cpp files, which is separating the interface from the implementation, and in doing so, removing implementation details from the interface.
This happens in different ways, in the simplest level how you implement a particular piece of functionality is irrelevant to the users of your component[*]. In many cases, you can have more types and functions in the .cpp file that are used just as details of implementation. Additionally, if you decide to implement a particular functionality directly or by depending on another library is a detail of implementation and should not leak to your users.
That separation might or might not be easy to implement in a tool that managed the separation of files automatically, and cannot be done by those that like the use of header only libraries.
Where some of you are claiming that there is no point in having to Go to definition, and would like to see the code altogether, what I see is the flexibility of deciding what parts of your component are details that should not be known by users. In many IDEs (and, heck, even in vim) there is a single keystroke combination that will take you from one to the other. In IDEs you can refactor the signature of the function and have the IDE apply the changes to both the header and the implementation (sometimes even to the uses)...
If you were to have a tool provide a unified view of both the header and implementation, it would probably be much harder to make the tool knowledgable of what parts of the code you are writing are part of the interface or the implementation, and the decisions that the tool might have could have an impact on the generated program.
The separate compilation model has its disadvantages but also advantages, and I feel that the discussion that is being held here is just scratching the surface of deeper design decisions.
[*] There seems to be quite a few people that believe that each class should have its own header and .cpp files, and I disagree, each header represents a component that might be a single class, or multiple classes and free functions the separation of code in files is part of the design, and in a single component you might have one or more public types together with possibly none or more internal types.
I don't know of any that makes the division into source/header completely transparent.
I do, however, know of some that make it considerably easier to handle. For example, Visual Assist X will let write your entire class in a header, then select member functions, and move them to a source file (i.e., a .cpp file).
That's not a complete cure (by any means), but it can/does make them much more bearable anyway.
Personally, I think it would be interesting to get rid of files completely, and instead use something like a database directly -- i.e., you have a database of functions, where the source code to that function is one column, object code another, internal compiler information about how to use it yet another, and so on. This would also make integrating version control pretty straightforward (basically just a stored transaction log).
I, for one, like the header files in C++, because they can serve as a "table of contents" of a sort, which gives you a quick overview of a class. This is, of course, assuming that you keep your headers short, and put the implementation of most functions into the .cpp.
Also, you can get plugins for Visual Studio that will move the implementation of a member function from the header into a .cpp for you. That, plus the "go to definition" and "go to declaration" commands in Visual Studio make headers very helpful for navigating a large code base.
Headers are pretty fundamental to the current compilation model of C++. I think there are things that would be a bit difficult to express without exposing the programmer directly to the header/cpp split. For example, in certain circumstances there's a significant difference between:
// header
class Foo {
Foo() = default;
}
and
// header
class Foo {
Foo();
};
// cpp
Foo::Foo() = default;
Despite that I think it would be worthwhile to think about improving the compilation model or making it easier to deal with.
For example, I can imagine a 'code bubbles' style IDE where the programmer writes definitions in code bubbles, and then groups bubbles together into translation units. The programmer would mark definitions as 'exported' to make them available to other TUs and for each TU he'd select exported items from other units to import. And all the while the IDE is maintaining it's own code bubble representation of the program, and when you build it generates the actual cpp files necessary for passing off to the compiler, creating forward declarations, etc. as needed. The cpp files would just be an intermediate build product.
There would be subtleties like the one I showed above though, and I'm not sure how the IDE I described would deal with that.

When should I consider making a library header-only?

Obviously template libraries need to be header only, but for non-templates, when should you make things header-only?
If you think your non-template library could be header-only, consider dividing it into two files anyway, then providing a third file that includes both the .h and the .cpp (with an include guard).
Then anyone who uses your library in a lot of different TUs, and suspects that this might be costing a lot of compile time, can easily make the change to test it.
Once you know users have the option which way to use the library, the answer probably becomes "offer that option whenever you possibly can". So pretty much any time that including it from multiple TUs wouldn't violate the ODR. For instance, if your non-static free functions refer to static globals, then you're out of luck, since the different definitions of that function in different TUs would refer to different objects by the same name, which is an ODR-violation.
You could follow Boost.Asio lead.
They simply provide the two versions of the libraries: header-only and header + library.
They do it with a single macro to be defined (or not) before including their headers. I think the default (if not defined) is to use the header-only version.
See Optional Separate Compilation.
Note how they neatly provide a single source file to be compiled that define everything or the option to link against a dynamically loaded library.
Template libraries need not to be header-only: implementations might well contain some pieces independent of template parameters, and for some reasons (e.g. less code size) separated into a special binary.
I cannot imagine a case where a non-template library really must be header-only. However sometimes it might be reasonable performance-wise to allow inlining of all the code. An example can be a library of wrappers around platform-specific interfaces, e.g. for things like synchronization primitives, thread-local storage, platform- and compiler-specific implementation of atomic operations etc.
Without templates, you'd have actual definitions in the headers. That means that if two files include your header, you'd get multiple definitions and the code will not compile.
In other words, putting definitions in headers is a very bad idea. You should stick to declarations only, and templates.
As for templates, compilers know that you may include the same header more than once, they will not generate the same code over and over again.
EDIT: If you mean "keep everything inlined", I think this is a very bad approach. The header files become completely unreadable, and any change in implementation forces any user of your library to recompile everything.

Rules of thumb for putting functions in header files

Lately I have started to put more and more functions into header files, mostly for convenience. But I fear I might be overdoing it, my headers are full of includes and I'm not sure if that's a good idea.
What are your rules of thumb for moving functions out of or into header files?
In case you're wondering, I'm talking about developing applications, not libraries.
Edit:
I guess it's helpful if I outline the pros/cons of inline (naturally) header functions versus implementation functions from my point of view:
Pro inline:
More clean/concise.
No need for signature duplication.
No need to change any Makefile to link against new files.
Instant ability to introduce template parameters.
Contra inline:
Increased compile time (I don't care that much)
Many includes in headers (Shouldn't be such a big issue if they use guards)
According to that, it seems like a good idea to put pretty much every function in headers, and I believe that's pretty close to what the STL and Boost are doing (although those are libraries, as opposed to my code).
One of my most inviolable rules: only function bodies which are inline are allowed in header files. Anything else is asking for trouble with multiple definitions in the link phase.
Headers should be left predominantly for declarations rather than definitions. I have exceptions to that rule (being the flexible type) but none of them involve non-inlined function bodies.
My rule of thumb is "Not in the header, unless you have to." And as for convenience, do you find increased compilation times convenient?
There are a few obvious technical aspects
- templates and inline functions must be in headers
- headers included from multiple translation units must be wary of the One Definition Rule
- more bluntly, you'd want a bloody good reason to even consider putting an out-of-line function implementation in a header, and I can't think of any times I've even been tempted.
So, the question boils down to:
inline in header versus out-of-line in implementation file?
Factors:
you say you're designing application level code not libraries, so you don't (currently) have to worry about other teams getting dependent on your code, nor minimise their need to recompile (versus just relink) by keeping implementation out of line
BUT if you're writing good code that has any potential to become useful to other teams, then you might find yourself wishing you'd kept implementation private
inline versus out-of-line typically represents about an order-of-magnitude overhead for trivial data get/set functions... if you have functions that are called repeatedly from performance critical code, then you've reason to prefer inlining
in-header implementation (especially if intermingled with the declarations) can often obfuscate the API, but sometimes actually makes the code more self-documenting
localisation and removed redundancy (of combining declaration/definitions) definitely removes potential for typos/errors and can often improve productivity
Bottom line: if you're finding yourself doing it more and more, then it's obviously working for you and there's no particular reason to think you're about to get burnt. Keep an eye out for the potential issues but don't over-engineer the heck out of stuff based on some hypothetical and unlikely-to-materialise concern.
A good coding standard will tell you to implement methods and functions in the source (cpp) file.
If you prefer it, you can implement templates and inline functions in the header.
Since this has been tagged as C++, why don't you seperate them into logical classes?
Normally I have one class declaration in a header file and it's definition in the corresponding source file.
The two rules I use are
1) If it's an inline functions
2) If it's a template function.
First, template function must be put in headers.
Besides, functions with an empty body, such as a default constructor or default but virtual destructor may be put in headers.
I never use inline because compiler don't guarantee that.

(C++) Whole class in .h file?

If I am creating a class with small functions that don't do much, is it acceptable to just put them all into the header file? So for a particular class, it's only just the .h with no .cpp to go with it.
Yes, that's acceptable. It will certainly compile. But also, if it makes the code organization cleaner, then that can be good. Most template definitions are already like this out of necessity, so you aren't doing anything unheard of. There can be some drawbacks of that class relies on other classes though. If you end up having to include the whole definition in other files that use the class, it may incur additional compile time compared to only having a brief class declaration.
You can measure your compilation times if this seems to be a real concern.
If you can get a copy, The c++ Programming Language (and many other books) have a detailed section about source code organization and the specific benefits of separating code into .h and .cpp files.
It depends what you are aiming for.
For a pet project, it's acceptable, but then anything is really.
For a real project, you need to ask yourself a number of questions:
do you have few dependencies ? (yes)
is your logic / implementation likely to change often ? (no, or see next question)
how much depends on this class ? (not much or much but it won't change)
If the responses satisfy you, then go ahead.
It is mainly a matter of dependency management. By putting the methods definition within the header, they are likely to get inlined by the compiler, which means that each time they change you'll have to recompile everything that depends on this class.
Templates do so, however templates generally have few dependencies (other includes) and you're relatively forced to proceed like so (though you can externalized non-template dependent code to cut down on dependencies).
For real big projects where dependency management is foremost, then I would advise against. In those projects a stable ABI and the ability to promote binary compatible changes are life-savers in case of issue and they are well worth the "slight" inconvenience for the developer.
In any case, please don't define the methods in the midst of the class. Even inlined you can define them after the class declaration. This makes it easier for people reading it (yourself in a few months) to get a grasp of the interface quickly.
Yes, it is acceptable. Moreover, if you do templates and you don't have a compiler with export support then you don't have a choice.
However, note that it can increase dependencies and thus make compilation slower.
It would be fine if you will use that header file in your future codes or projects, and if you want to share it with the others.
Depends on how you're linking. To avoid having to see messages such as redefinition of blah, previous definition in file blah.h on line 13 just put everything but the declaration in a .cpp.

What are the advantages and disadvantages of implementing classes in header files?

I love the concept of DRY (don't repeat yourself [oops]), yet C++'s concept of header files goes against this rule of programming. Is there any drawback to defining a class member entirely in the header? If it's right to do for templates, why not for normal classes? I have some ideas for drawbacks and benefits, but what are yours?
Possible advantages of putting everything in header files:
Less redundancy (which leads to easier changes, easier refactoring, etc.)
May give compiler/linker better opportunities for optimization
Often easier to incorporate into an existing project
Possible disadvantages of putting everything in header files:
Longer compile/link cycles
Loss of separation of interface and implementation
Could lead to hard-to-resolve circular dependencies
Lots of inlining could increase executable size
Prevents binary compatibility of shared libraries/DLLs
Upsets co-workers who prefer the traditional ways of using C++
Well - one problem is that typically implementations change much more often than class definitions - so for a large project you end up having to recompile the world for every small change.
The main reason not to implement a class in the header file is: do the consumers of your class need to know its implementation details? The answer is almost always no. They just want to know what interface they can use to interact with the class. Having the class implementation visible in the header makes it much more difficult to understand what this interface is.
Beyond considerations of compactness and separating interface from implementation, there are also commercial motivations. If you develop a library to sell, you (probably) do not want to give away the implementation details of the library you are selling.
You're not repeating yourself. You only write the code once in one header. It is repeated by the preprocessor, but that's not your problem, and it's not a violation of DRY.
If it's right to do for templates, why not for normal classes
It's not really that it's the right thing to do for templates. It's just the only one that really works in general.
Anyway, if you implement a class in a header, you get the following advantages and disadvantages:
The full implementation is visible anywhere it is used, which makes it easy for the compiler to inline as necessary.
The same code will be parsed and compiled multiple times, leading to higher compile-times.
On the other hand, if everything is in headers, that may lead to fewer translation units, and so the compiler has to run fewer times. Ultimately, you might end up with a single translation unit, which just includes everything once, which can result in very fast compilations.
And... that's it, really.
Most of my code tends to be in headers, but that's because most of my code is templates.
The main disadvantage (apart from the lengthy builds) is there is no clear separation of the interface and implementation.
Ideally, you should not need to see the implementation of an intuitive, and well documented interface.
Not mentionned yet: virtual functions are instantiated for each include, so you can bloat your executable (I'm not sure whether this is true for all compilers).
There is an alternative:
Do a lot of stuff in classes declared in your source-file. 1 example is the pimpl-idiom, but there are also people who are afraid to declare classes out of the header-file. However, this makes sense for private classes.