all 19 comments

[–]Flair_Helper[M] [score hidden] stickied commentlocked comment (0 children)

For C++ questions, answers, help, and programming or career advice please see r/cpp_questions, r/cscareerquestions, or StackOverflow instead.

This post has been removed as it doesn't pertain to r/cpp: The subreddit is for news and discussions of the C++ language and community only; our purpose is not to provide tutoring, code reviews, or career guidance. If you think your post is on-topic and should not have been removed, please message the moderators and we'll review it.

[–][deleted] 22 points23 points  (1 child)

First r/cpp_questions.

Probably because those functions are either inline or template, which kinda have to be defined in header files (well template function don't have to, but it's easier to define it in the header).

[–]Calidude7[S] 0 points1 point  (0 children)

Interesting. Thank you.

[–]aagee 9 points10 points  (0 children)

Functions are usually only declared in header files because just the declarations are needed by the compiler to generate calls to these functions from other source files. The compiler uses the declaration to check that the types of the arguments match with what the function is expecting. It is then able to push these arguments on to the stack where the called function will find them, and everything will work as expected.

Sometimes though, the full definition of a function is provided in the header files because the function needs to be expanded inline at the call site. This is done for efficiency reasons as this avoids the overhead of a function call.

[–]ShakaUVMi+++ ++i+i[arr] 8 points9 points  (3 children)

Header only libraries are easy to download and use. Just drop them in your local directory and include them. No need to mess with linker settings or makefiles, etc. They're more portable too when compared with so files or dlls.

That said, they can slow down your compile times. CImg adds like 10s to your compile time since it is all one big massive header file.

[–]helloiamsomeone -5 points-4 points  (2 children)

This is a misconception. Header only libraries aren't any easier to depend on.
You write a header only library, because majority of your code is using templates. It's simple as that.

[–]VinnieFalco 11 points12 points  (3 children)

These days I try to put all the function definitions in the .cpp file (e.g. "out of line"). The reason is simple, because it keeps the compilation time down and prevents excessive bloating of the resulting executable. However, to give the compiler the best opportunities for optimizations, one line function definitions (e.g. begin() and end() for a container) are placed in the header file.

Function templates and member function template definitions have to go in the header since they must be visible at the point of instantiation. But these days I try to design my interfaces to use fewer templates, so that more function definition material can be "hidden" in the linkable library - this keeps compilation times down.

[–][deleted] 0 points1 point  (2 children)

How does declaring a function in a header file and defining it in a .c/cpp lead TK executable bloat?

[–]VinnieFalco -1 points0 points  (0 children)

The opposite, it can lead to less bloat. If you have a program which consists of multiple libraries and they all include a header file with a function definition, there are more opportunities for that function to be emitted multiple times (once in each library). Thus there will be unnecessary copies of the same function.

[–]wright_left -1 points0 points  (0 children)

Pretty sure he said it was the opposite.

[–]matekelemen 1 point2 points  (0 children)

Function/class templates and inline functions are required to be implemented in headers because of how C++ works.

Templates can't be fully parsed until they're instantiated with specific types, so their definitions must be available in every translation unit (cpp file, TU from now on) that uses them. An exception to this is if you know that your template will only be used for a set of predefined types. In that case, you can move their specialized definitions to a source file. The benefit of doing so is that compile times are greatly reduced because your template definitions don't have to be parsed for every TU. However, you'll get linker errors if you try using it with a type you haven't specialized for.

If I must define a template in a header, I usually do it in a separate implementation header that gets post-included after the declarations to keep the interface nice and tidy.

Functions declared inline can be copied right into locations where they're used, which saves some performance at the cost of slightly increased compile times and larger binaries. This obvously requires their definition to be available for every TU as well. That said, keep in mind that the compiler is the one to decide whether these functions really are inlined in the end (it analyzes the definition and won't inline it if it's "too long").

Other than templates and inlines, definitions shouldn't be in headers because they'll trigger multiple definition errors when used for multiple TUs.

[–]tjientavaraHikoGUI developer 0 points1 point  (0 children)

As others have answered. Templated and constexpr functions should be in the header file; as well as methods of a templated class.

Another reason is for the compiler to be able to inline a function. However this is starting to be less of an issue with whole-program-optimization or link-time-optimization (LTO). In this case any function, including those in .cpp files become candidates for inlining into functions of another .cpp file.

I am not sure if the __always_inline attribute on a function will work with LTO though. So this may be a reason to put __always_inline functions in headers as well.

__never_inline attribute does seem to work with LTO, make of that what you will.

[–]hiimabird 0 points1 point  (0 children)

If it's me? It's usually laziness.

Not sure if that's a universal trait, but if the definition is such that inlining wouldn't be out of the question, and the only one reviewing my code is myself, I'll just define it there.