Recently reading some pieces of code I encountered several .cpp files that contained
#pragma once in the beginning of file. I know that it is usually used in .h files as guards.
What are the cases when #pragma once should/can/must be used in .cpp files?
#pragma once shouldn't be used in source files, its one goal is to act as include guard. It won't do much harm .cpp files are normally going to be "scanned" once during compilation anyway. Note: Clang tidy will warn you if you do it.
Warning clang-diagnostic-pragma-once-outside-header #pragma once in main file
Related
I have a few queries regarding the design principle of laying out a C++ header and source files:
I have recently taken over a project in which the previous programmer used to have this, which is particularly annoying because I read somewhere that we shouldn't include a .cpp file in a .hpp file (The preprocessor will just copies and pastes the .cpp file into a .hpp)
Q1. Including a .cpp file in a .hpp file is bad? why?
Due to the problem above, I am facing many "multiple declaration" errors when I load my program in eclipse, even though i added the header guards in all the .hpp files.
Q2. Should i be including the header guards in the .cpp files as well?
I tried the later too but to no avail. Any suggestions on this?
Q3. If 2 or more of my .cpp files need the same header files to be
used what is the best way to include all those header files? Should i
create a new header file say h1.hpp, include all the header files I
need in those 2 or more .cpp files and later include in this header
file in those .cpp files(s)?
Is it an efficient approach ?
Including a .cpp file in a .hpp file is bad? why?
In a typical code setup, yes. It serves no useful purpose and can lead to "duplicate definition" errors.
More importantly, it mixes the separation between the implementation and interface parts. When a file containing implementation is meant to be included, it's often changed to .inl (from "inline") extension.
Should i be including the header guards in the .cpp files as well?
No. Header guards prevent two (or more) other headers in one translation unit from including the same header twice. Since there's only one .cpp file per translation unit, this problem doesn't occur there.
To illustrate, an example inclusion could look like this:
common.hpp
/ \
/ \
A.hpp B.hpp
\ /
\ /
file.cpp
In this case, header guard in common.hpp prevents it from appearing twice in the TU introduced for file.cpp.
If 2 or more of my .cpp files need the same header files to be used what is the best way to include all those header files?
You shouldn't be scared by a long include chain, in general. It's less scary than it looks. That being said, "aggregate" headers can be used if the headers actually form a tree structure (to make including subsets easier, like collections.hpp and collections/vector.hpp + collections/list.hpp) or to include every header from the library.
I am having trouble understanding an answer I saw in another post. It said that it is good practice to define a struct in a separate .h file so it can be used in other files. I think that is great and it solves my current dilemma, however I have a question about compilation and makefiles. I am only familiar with having header files that are associated with .cpp files at the moment.
Can someone explain how that implementation would look when I have a .h and no .cpp? Do I need an implementation file as well? Also, how do I link the header in a makefile? Currently I only know how to compile a .cpp & header into a .o file and link them.
Thanks, and sorry for taking us back to c++ kindergarten. This is a new revelation and seems like a good one.
You don't need a matching source file (.c or .cpp) for every header .h file.
Having header files without corresponding source files is just fine.
When you #include some header file, you can think of it as a kind of "copy and paste" operation: the preprocessor copies the content of the header file, and pastes it in the point of inclusion.
(Well, there are some details to consider here, for example the presence of a #pragma once directive or some #ifdef inclusion guard can prevent multiple inclusions of the same header file in a given project.)
The C and C++ compilers will then process the whole "compilation unit", i.e. the current source file with all the included headers.
The key concept is that you define the struct/class in a .h header, so that you can use it in multiple .cpp files. Whenever you need struct foo defined in foo.h, you #include "foo.h". You don't need to directly compile the header file, it will be pulled in by whichever source file uses it. Therefore you don't need a make target for .h in normal circumstances.
If the definition in the header is never used, it won't be pulled in and that's it.
I've searched all over for some clarification on what
#pragma once
actually does and can't find definitive answers for some questions I still have.
Does
#pragma once
insure that the header file it is included in is only called once AS WELL AS that the headers which are included in said header file are not yet included? Also, if it is only called once, does that mean a .cpp file that needs a particular header will not be able to access it? If a header file is marked with
#pragma once
and included in a .cpp, can that header file be used again elsewhere?
These are the sorts of clarifications I am not finding. Sorry if there is documentation that clarifies this somewhere, but I really couldn't find any thing specific enough.
#pragma once only guards a single file in a single translation unit, not counting its sub-hierarchy of inclusion. (However, if the file's second inclusion is prevented, it doesn't have an opportunity to doubly-include anything else.)
You can still include it again from another .cpp.
The file is usually identified by its inode number.
Note that #pragma once is strictly nonstandard, and most still prefer traditional #ifndef header guards.
#pragma once causes the current source file to be included only once in a single compilation.
It's essentially similar to #include guards.
Does #pragma once insure that the header file it is included in is only called once AS WELL AS that the headers which are included in said header file are not yet included?
The pragma doesn't affect other headers. if the header with the pragma 'a.h' includes 'b.h', 'b.h' can be included again via a third header or directly.
Also, if it is only called once, does that mean a .cpp file that needs a particular header will not be able to access it?
You can include the header from anywhere you want, as many times as you see fit.
If a header file is marked with #pragma once and included in a .cpp, can that header file be used again elsewhere?
Yes, this is the normal practice with headers.
Where's the catch?
If you really need to include the headers more than once and every include performs a different operation than don't use pragma once or a sentry macro. These cases are not common.
A benefit to pragma once is that it saves you from bugs like having 2 header files that by chance have the same sentry macro. this can happen when 2 header files have the same file name and same coding style for macro names.
I am running my programs in Ubuntu using a library names cpt. I am including the required header files from the library but the program does not work because it is unable to access the functions in the header file. ( it shows that error ) I have to include the .cpp files as well which contains the function's complete definition.
I am now running my programs by also including the .cpp files associated with the required headers. Why I am getting this error inspite of the fact that I have -I/Desktop/cpt while compiling ?
You should not include .cpp files, they should be compiled, you should specify to your compiler which .cpp files to compile, and where to find the .h files the .cpp files require.
Maybe you should link your program with the corresponding shared/static library that provides the implementation of those functions declared in the header file?
Vladimirm is correct, you do not need to #include the .cpp files. the header files should compile with or without their associated .cpp files. All of the .cpp files are linked together in a process known as linking, but the header files provide prototypes for functions during linking.
Are you using angle brackets around your #include? e.g.
#include <mylib.h>
If so, you might consider switching to double quotes, e.g.
#include "mylib.h"
Depending on where the source files you are referencing are located, this could be the issue.
There is a .h file and a .cpp file with the same name but different extension.
If I want to use what's in the .cpp file, do I include the .h file or the .cpp file?
The simple answer is that you almost always want to include .h files, and compile .cpp files. CPP files are (usually) the true code, and H files are (usually) forward-declarations.
The longer answer is that you may be able to include either, and it might work for you, but both will give slightly different results.
What "include" does is basically copy/paste the file in at that line. It doesn't matter what the extension is, it will include the contents of the file the same way.
But C++ code is, by convention, usually written this way:
SomeClass.cpp -
#include "SomeClass.h"
#include <iostream>
void SomeClass::SomeFunction()
{
std::cout << "Hello world\n";
}
SomeClass.h -
class SomeClass
{
public:
void SomeFunction();
};
If you include either of those, you can use the code from it. However, if you have multiple files that include the same .cpp file, you may get errors about re-definition. Header files (.h files) usually contain only forward declarations, and no implementations, so including them in multiple places won't give you errors about re-definition.
If you somehow manage to compile without errors when including .cpp files from other .cpp files, you can still end up with duplicate code. This happens if you include the same .cpp files in multiple other files. It's like you wrote the function twice. This will make your program bigger on disk, take longer to compile, and run a bit slower.
The main caveat is that this implementation/forward declaration convention doesn't hold true for code that uses templates. Template code will still be handed to you as .h files, but it (usually) is implemented directly in the .h file, and won't have accompanying .cpp files.
Usually it's better to write in the header file .h
#ifndef H_someClass
#define H_someClass
class SomeClass {
public:
void SomeFunction();
};
#endif
so that you won't get errors about re-definition when you need to include the .cpp file in other files.
The .h file usually contains the class declaration and the .cpp file the class definition (implementation). You should include the .h in the .cpp file.
A good rule of thumb is to NEVER include a .cpp file, because the #include directive just copies the content of the included file into the including file. You may end with some multiple inclusion / definition and you definitely don't want to do that.