Many other questions deal with how to allocate a variable by declaring it in a header file and defining it (allocating) in a .cpp file.
What I want to do is not use any .cpp files for my class, and to define all functions as inline (in the header file). The problem that I run into is how to define static member variables so that even when the .h file is included in multiple compilation units I don't get the "first defined here" linker error.
I'm open to preprocessor hacks, etc. if it gets the job done. I just want to avoid any .cpp files.
If it matters I'm using GCC.
You can abuse the singleton pattern if you really must avoid any .cpp files:
class Foo {
public:
static Bar& getMyStatic() {
static Bar bar;
return bar;
};
};
This works because now the variable is a static variable inside a function, and static has a different meaning within a function context than within a class context. And for functions, the linker does recognize multiple identical definitions and throws away the copies.
But, of course, I would strongly advise against avoiding .cpp files: It means that you get into a situation where you have to build the entire program, or at least large parts of it, in one big piece. Every change you do will necessitate a complete rebuilt which slows down your change-compile-test cycle significantly. For very small projects that might not be a problem, but it is for medium to large ones.
With static variables you have to put in a .cpp file to avoid the possibility of multiple static variables when the intention is to have just the one. Besides it is not a good idea to have large inline methods as it is only a hint to the compiler but also makes compilation take longer (you change some of those functions in development and then lots of dependent files will need to get compiled!)
However if you do not want lots of .cpp files with just a few statics in it why not have just one file to store them in.
As long as you only include that header file once in your whole project, you'll be OK. However, that's a pretty strong requirement, and can be difficult to make others adhere to.
You could have a static variable, but that means you have more than one for the entire program, which may or may not matter (bear in mind that you can't change it in the future, so you may have what's known as a "latent bug" - you change some other code, and all of a sudden you have created a new bug, because the variable isn't ONE variable).
Related
I am working on a game,
I have a huge list of const global variables .h file which many .cpp file relies on.
(Enemies would like to know the max hp of players etc)
However, this is a compilation nightmare when any variable is changed in the file for game balancing.
I would like to prevent splitting up the files into multiple headers for the ease of the guy in charge of game balancing.
However, recategorizing is kind of a pain (clarity vs compile time, Player's maximum hp is used in many .cpp but it should belong to the PlayerVariables.h, including it in every file that uses it kind of destroys the purpose of splitting them up).
Is there a way to save some time other than the method above?
Just declare the global variables in the header file. And define them in another source file. That way if any of the values are changed only the globals.cpp needs to be recompiled since everything includes globals from the hpp.
In globals.hpp:
extern const unsigned PLAYER_MAX_HEALTH;
In globals.cpp:
#include "globals.hpp"
const unsigned PLAYER_MAX_HEALTH = 100;
You could try adding a configure-step with the preprocessor:
Only have preprocessor #defines in the config.h
Split it with the preprocessor into multiple headers only pulling in those definitions they need to declare actual const variables / enum-values / whatever.
Only copy those files which are different from the previous run over the previous version.
Optionally also have a glabals.cpp defining those symbols which might also need a definition.
Make sure to (re-)run make after the configuration was updated.
The advantage over just declaring external constant variables and defining and initializing them in a different translation-unit is constant-propagation and having proper compile-time-constants.
Why is it a bad practice to define the functions of the class in the header files?
Lets say I have a header file and I define the functions of the class in the class definition itself like,
headerfile.hpp
#ifndef _HEADER_FILE_
#define _HEADER_FILE_
class node{
int i;
public:
int nextn(){
......
return i;
}
}
#endif //_HEADER_FILE_
So defining the function in the class like this makes the function "Inline".So if we include this header file in say two .cpp files, will it cause "Multiple definition error" ??Is it a bad practice to define the functions like this in the class definition?
It is a bad practice for the following reasons: If you need to change the code, let's say to add a trace in a simple setter (they are commonly in the .h); then you will need to recompile all CPP files that #includes the change (and any dependency of). In my current project that could reach up to 1 hour lost. If you later need to add another trace, then another and so on you quickly loose 1-2 days or work waiting for the compiler.
If you place your code in the CPP, then you only need to re-link, and that takes only a few minutes. Your project may be small today, but who knows in a few years. It's just a good habit to take.
Another (not so good) reason is that if you search your code base for the string "::MyFonction" you will not find it in the declaration since there is no "::" (we only want implementations). But a good IDE should find it anyway using a context search instead of a string search.
It's not bad practise (in fact it's commonplace) and it will not cause multiple definition errors. Inline functions never cause multiple definition errors, that's one of the meanings of inline.
The convention to separate prototypes (that is, the declaration of the class, its functions, their types) from implementation comes from both a design and a performance point of view.
Type checking and compiling your dependants is cheaper. Something that uses your class can be safely compiled without knowing your implementation.
Your compiler won't need to parse and recompile the same information lots of times each time you do compile those dependants.
The thing is to remember what it really means with you write #include at the top of a file in C++: it means "take all the contents of some other file, and put them here." So if you're using a class in lots of places all over your code base, then it's getting parsed every single time, and re-compiled in the context of that compilation unit.
This is precisely the reason why you have to put implementations of template classes in-line in the header file; the compiler needs to re-parse and compile the class for every different template instantiation (because that's what templates are about).
To answer your question directly:
* No, you will not get a multiple definition error.
* Maybe, some people would consider it back practice from a design points of view (others wouldn't)
* You might see a difference in performance (though not necessarily a degredation, as I believe - though I could be wrong), that despite the above, it can still be faster to compile header-only libraries.
Probably avoid doing this if your implementations are long, the class is used often in the codebase, and will be subject to frequent change.
For further reading, it might be worth checking up on "precompiled headers."
It is legal to define (inline) functions in your hpp file. Note that some people prefer to gather then under a dedicated extension like "inl.hpp", but this is just a style preference.
I have a number of C++ classes, alot of them (not all) share two "static size variables" e.g.
share.h
/*Other variables in this header used by all classes*/
static size width=10;//Used by about 60%
static size height = 12;//used by about 60%
So I placed them in a header file along with other objects that all classes share.
when I compile the project I get alot of warnings (from the classes which dont use these), which complain about them being defined and not used. But I need them there!
So I ask, is there a way to hash these to prevent such warnings?
Hashing them so that they can be defined! preventing warnings from classes calling this header file which dont require these last two variables, but they call header because they need everything else init
You should place them in an individual header file. So you can include it only in the classes they need it. This avoids the warning in the other classes. So in the end you will have two header files. One where the stuff for all classes is included and another where the variables which are not used in all are defined.
However try to avoid global variables.
Edit reading tune2fs' answer, I realized I may have interpreted the question wrong.
Perhaps you forgot to use extern in the header file? If you just include static definitions in the header file all compilation units will have unique copies, not shared. See also this explanation of static/extern
Edit Disambiguated in comments
static SomeClass NotUnusedInstance;
static void unused_vars_helper()
{
static SomeClass* take_address = &NotUnusedInstance;
}
This approach is design to have minimal impact (not invoking any actual code; take_address isn't actually initialized unless you call unused_vars_helper).
This should work pretty well for your case. You can make unused_vars_helper() static and/or move it inside an anonymous namespace to prevent external visibility of the helper.
I know what it means when static function is declared in source file. I am reading some code, found that static function in header files could be invoke in other files.
Is the function defined in the header file? So that the actual code is given directly in the function, like this:
static int addTwo(int x)
{
return x + 2;
}
Then that's just a way of providing a useful function to many different C files. Each C file that includes the header will get its own definition that it can call. This of course wastes memory, and is (in my opinion) a quite ugly thing to be doing, since having executable code in a header is generally not a good idea.
Remember that #include:ing a header basically just pastes the contents of the header (and any other headers included by it) into the C file as seen by the compiler. The compiler never knows that the one particular function definition came from a header file.
UPDATE: In many cases, it's actually a good idea to do something like the above, and I realize my answer sounds very black-and-white about this which is kind of oversimplifying things a bit. For instance, code that models (or just uses) intrinsic functions can be expressed like the above, and with an explicit inline keyword even:
static inline int addTwo(int *x)
{
__add_two_superquickly(x);
}
Here, the __add_two_superquickly() function is a fictional intrinsic, and since we want the entire function to basically compile down to a single instruction, we really want it to be inlined. Still, the above is cleaner than using a macro.
The advantage over just using the intrinsic directly is of course that wrapping it in another layer of abstraction makes it possible to build the code on compilers lacking that particular intrinsic, by providing an alternate implementation and picking the right one depending on which compiler is being used.
It will effectively create a separate static function with the same name inside every cpp file it is included into. The same applies to global variables.
As others are saying, it has exactly the same meaning as a static function in the .c file itself. This is because there is no semantic difference between .c and .h files; there is only the compilation unit made up of the file actually passed to the compiler (usually named .c) with the contents of any and all files named in #include lines (usually named .h) inserted into the stream as they are seen by the preprocessor.
The convention that the C source is in a file named .c and public declarations are in files named .h is only a convention. But it is generally a good one. Under that convention, the only things that should appear in .h files are declarations so that you generally avoid having the same symbol defined more than once in a single program.
In this particular case, the static keyword makes the symbol be private to the module, so there isn't a multiple-definition conflict waiting to cause trouble. So in that one sense, it is safe to do. But in the absence of a guarantee that the function would be inlined, you take the risk that the function would be instantiated in every module that happened to #include that header file which at best is a waste of memory in the code segment.
I am not certain of what use cases would justify doing this at all in a generally available public header.
If the .h file is generated code and only included in a single .c file, then I would personally name the file something other than .h to emphasize that it isn't actually a public header at all. For example, a utility that converts a binary file into an initialized variable definition might write a file that is intended to be used via #include and could very well contain a static declaration of the variable, and possibly even static definitions of accessor or other related utility functions.
If you define the function in a header file (not simply declare it), a copy of the function will be generated in each translation unit (basically in each cpp file which includes this header).
This may increase the size of your executable, but this may be negligible if the function is small. The advantage is that the most compilers may inline the function, which may increase the code performance.
But there may be a big difference in doing this which wasn't mentioned in any answer. If your function uses a static local variable such as:
static int counter()
{
static int ctr = 0;
return ctr++;
}
Rather than:
//header
int counter();
//source
int counter()
{
static int ctr = 0;
return ctr++;
}
Then each source file including this header will have its own counter. If the function is declared inside the header, and defined in a source file, then the counter will be shared across your whole program.
So saying that the only difference will be performance and code size is wrong.
There is not semantic difference in defining in source file or header file, basically both means the same in plain C when using static keyword that, you are limiting the scope.
However, there is a problem in writing this in header file, this is because every time you include the header in a source file you'll have a copy of the function with same implementation which is much similar to have a normal function defined in header file. By adding the definition in header you are not achieving the what the static function is meant for.
Therefore, I suggest you should have your implementation only in your source file and not in header.
It is usefull in some "header-only" libraries with small inline functions. In a such case you always want to make a copy of the function so this is not a bad pattern. However, this gives you an easy way to insert separate interface and implementation parts in the single header file:
// header.h
// interface part (for user?!)
static inline float av(float a, float b);
// implementation part (for developer)
static inline float av(float a, float b)
{
return (a+b)/2.f;
}
Apple vector math library in GLK framework uses such constuction (e.g. GLKMatrix4.h).
Should you declare the getters/setters of the class inside the .h file and then define them in .cpp Or do both in .h file. Which style do you prefer and why? I personally like the latter wherein all of them are in .h and only methods which have logic associated with it other than setters/getters in .cpp.
For me it depends on who's going to be using the .h file. If it's a file largely internal to a module, then I tend to put the tiny methods in the header. If it's a more external header file that presents a more fixed API, then I'll put everything in the .cpp files. In this case, I'll often use the PIMPL Idiom for a full compilation firewall.
The trade-offs I see with putting them in the headers are:
Less typing
Easier inlining for the compiler (although compilers can sometimes do inlining between multiple translation units now anyway.)
More compilation dependencies
I would say that header files should be about interface, not implementation. I'd put them in the .cpp.
For me this depends on what I'm doing with the code. For code that I want maintained and to last over time, I put everything in the .cc file for the following reasons:
The .h file can remain sparse as documentation for people who want to look for function and method definitions.
My group's coding guidelines state that we put everything in the .cpp file and like to follow those, even if the function definition only takes one line. This eliminates guessing games about where things actually live, because you know which file you should examine.
If you're doing frequent recompiles of a big project, keeping the function definition in the .cpp file saves you some time compared to keeping function definitions in header files. This was relevant very recently for us, as we recently went through the code and added a lot of runtime assert statements to validate input data for our classes, and that required a lot of modification to getters and setters. If these method declarations had lived in .cpp files, this would have turned into a clean recompile for us, which can take ~30min on my laptop.
That's not to say that I don't play fast-and-dirty with the rules occasionally and put things in .h files when implementing something really fast, but for code I'm serious about I all code (regardless of length) in the .cpp file. For big projects (some of) the rules are there for a reason, and following them can be a virtue.
Speaking of which, I just thought of yet another Perl script I can hack together to find violations of the coding guidelines. It's good to be popular. :)
I put put all single-liners in the header as long as they do not require too much additional headers included (because calling methods of other classes).
Also I do not try to put all code in one line so I can put most of the methods in the header :-)
But Josh mentioned a good reason to put them in the .cpp anyway: if the header is for external use.
I prefer to keep the .h file as clean as possible. Therefore, small functions that are as simple as get/set I often use to put in a separate file as inline-defined functions, and then include that file (where I use the extension .inl) into the .h header file:
// foo.h
class foo
{
public:
int bar() const;
private:
int m_bar;
};
#include "foo.inl"
// foo.inl
inline
int foo::bar() const
{
return m_bar;
}
I think that this gives the best of two worlds, at the same time hiding most of the implementation from the header, and still keep the advantage of inlining simple code (as a rule of thumb I keep it within at most 3 statements).
I pretty much always follow the division of declaring them in the header, and defining in the source. Every time I don't, I end up having to go back and do it any way later.
I prefer to put them into the .cpp file, for the sake of fast compile/link times. Even tiny one-liners (empty virtual destructors!) can blow up your compile times, if they are instantiated a lot. In one project, I could cut the compile time by a few seconds by moving all virtual destructors into the .cpp files.
Since then, I'm sold on this, and I would only put them into the header again if a profiler tells me that I can profit from inlining. Only downside is you need more typing, but if you create the .cpp file while you write the header, you can often just copy&paste the declarations and fill them out in the .cpp file, so it's not that bad. Worse of course if you later find out you want to move stuff into a .cpp file.
A nice side effect is that reading stuff is simpler when you have only documentation and declarations in your header, especially if new developers join the project.
I use next rule: header for declaration, code file for realization. It becomes for actual when your header would be use outside of project - than more lightweight your header is, then it's more comfort in use