Under what conditions are C++ headers not transitive? - c++

I've just run into a condition where I #include a header, I run into compilation errors that require me #including headers that were already included in the original header.
The header has the following contents:
#pragma once
#include <atlbase.h>
#include <atlcom.h>
#include "itestobj.h"
extern "C" ITestObj* WINAPI GetTestObj();
I then get a bunch of ATL-related compilation errors when I code against that which are resolved by including atlbase.h and atlcom.h in the C++ file in addition to the above header.
Why aren't these headers being included as would normally seem to be the case?

In all likelihood, at least one of these headers is including the file you show in your post. Since #pramga once tells your compiler to include it only once, it stops and you don't get all declarations.

Related

C++ Header Guard Syntax and Header Placement

My question is on proper syntax and usage of header guards. For example if I am including a few common libraries in my C++ code can I make a header guard like what is shown below? Also, from the documentation I could find on header files it was suggested to put your header guard in a header file. I am using Microsoft Visual Studio. Can I just place my header guard and #include files in my main source file? Or is this a bad practice? I know you can use #pragma to function as a header guard. However, this is not a supported standard so I am trying to avoid using it.
#ifndef HEADER_GUARD
#define HEADER_GUARD
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#endif
Any help would be greatly appreciated!
You should not write the header guard in source code (.cpp) file.
We should avoid the double header guard as well The use of double include guards in C++
Header guard is to avoid multiple time inclusion of header file during compilation of code.
Also, while adding the #include file, keep in mind that we should not add the unwanted files there.
e.g.
Consider case if source file requires to #include <iostream> but you included in header file then this should be avoided. Such case #include <iostream> in source file only.
#pragma once is supported by many compilers but it's not language standard and it do not guarantee when file are referenced from remote location and different disks.

How to use precompiled header with dynamic library and console application?

I have the problem with precompiled header. It looks somewhat like that
ftpch.h
#pragma once
#include <vector>
#include <iostream>
#include <string>
#include <Windows.h>
ftpch.cpp
#include "ftpch.h"
Then I have a header file and cpp in my dll library.
test.h
#pragma once
// DLL_EXPORT is a macro that changes for dll and console app like that:
// __declspec(dllexport) and __declspec(dllimport)
class DLL_EXPORT Test
{
std::string foo() {return "ara ara"};
}
And this code compiles fine when I compile my dynamic library project, but fails to compile when I include "test.h" in my console app project and try to compile it. The error I get is:
C2039: 'string' is not a member of 'std'
Your header files should always be self-sufficient. Include your libraries (in this case <string>) where you need them, everywhere you need them, and only where you need them.
If your header requires a certain library to function, include it in that file; don't reply on a different header to have included that library already, because if that different file changes, you're out of luck.
You've already got #include guards through #pragma once, so adding #include <string.h> to the header files that need it won't cause collision, and will also make them more maintainable and easy to interpret.

#define XYZ before #include precompiled header

I am refactoring some existing software and I regularly see this
#define XYZ
#include "stdafx.h"
where stdafx is the precompiled header file.
Q1. Can a knowledgeable person please confirm the following?
That (except perhaps for the file stdafx.cpp) the correct order is always
#include "stdafx.h"
#define XYZ
My reasoning is as follows. A define before the precompiled header can't affect the precompiled header even if 'used' inside the header, since the header is precompiled. The precompiled header will have used whatever the macro XYZ was set to when the initial compilation took place.
So
#define XYZ
#include "stdafx.h"
misleads a reader into thinking XYZ may have an influence on the contents of stdafx.h.
Q2. Whether the two are functionally equivalent and my refactoring is safe?
#include "stdafx.h"
#define XYZ
clearly defines XYZ whereas the alternative does not so clearly define it. (Using the precompiled header might well overwrite the definition with some compilers, for all I know.) Yet defining XYZ before including the precompiled header does seem to work, as it is present so often in the code I am refactoring.
Q3. Is the behaviour defined in a standard?
If I were the compiler writer, I would reject any #define prior to inclusion of a precompiled header! My VS2019 doesn't.
You state:
A define before the precompiled header can't affect the precompiled header even if 'used' inside the header, since the header is precompiled.
But from the Microsoft documentation Precompiled Header Files:
[#defines] Must be the same between the compilation that created the precompiled header and the current compilation. The state of defined constants is not checked, but unpredictable results can occur if your files depend on the values of the changed constants.

Including a library in both the header file and the cpp file

I am new to C++. I have seen code that includes a library file (string as an example) in both the header and cpp file. Will this cause duplicate code if #ifndef is not used? or is the preprocessor smart enough to ignore it. Is it normal to include the same library in both files?
test.h
#include <string>
.
.
.
test.cpp
#include <string>
#include "test.h"
.
.
.
Is it normal to include the same library in both files?
Yes. It is normal to include a header into multiple files.
Whenever you use a declaration from a header, you should include that header. If you use std::string in test.h, then you should include <string> in test.h. If you use std::string in test.cpp, then you should in include <string> in test.cpp. Whether <string> happens to be included in one of the headers included by test.cpp is irrelevant and is something that shouldn't be relied upon.
Will this cause duplicate code if #ifndef is not used?
If a header doesn't have a header guard, then including it multiple times will indeed cause its content to be duplicated, yes.
or is the preprocessor smart enough to ignore it.
The preprocessor doesn't ignore any includes. Each include will be processed. A preprocessor may be smart enough to optimise inclusion of a header that it knows would be empty due to an include guard.
All C++ standard library header files have ifndef guards. It is safe to include them in multiple files.
The rule of thumb is to include the file everywhere where its definitions are needed. This means if you're using std::string in both h and cpp files, include <string> in both.
For any of your own header files, you should always use ifndef guards for the same purpose.

Comprehension issue: Precompiled headers & include usage

I got a comprehension issue about precompiled headers, and the usage of the #include directive.
So I got my "stdafx.h" here and include there for example vector, iostream and string. The associated "stdafx.cpp" only includes the "stdafx.h", that's clear.
So if I design my own header file that uses for example "code" that's in vector or iostream, I have to include the header file because the compiler doesn't know the declarations at that time. So why are some posts here (include stdafx.h in header or source file?) saying, it's not good to include the "stdafx.h" in other header files even if this file includes the needed declarations of e.g. vectors? So basically it wouldn't matter to include directly a vector or the precompiled header file, both do the same thing.
I know of course, that I don't have to include a header file in another header file if the associated source file includes the needed header file, because the declarations are known at that time. Well, that only works if the header file is included somewhere.
So my question is: Should I avoid including the precompiled header file in any source file and why? And I am a bit confused, because I'm reading contradictory expressions on the web that I shouldn't include anything in header files anyway, or is it O.K. to include in header files?
So what's right now?
This will be a bit of a blanket statement with intent. The typical setup for PCH in a Visual Studio project follows this general design, and is worth reviewing. That said:
Design your header files as if there is no PCH master-header.
Never build include-order dependencies in your headers that you expect the including source files will fulfill prior to your headers.
The PCH master-header notwithstanding (I'll get to that in a moment), always include your custom headers before standard headers in your source files. This makes your custom header is more likely to be properly defined and not reliant on the including source file's previous inclusion of some standard header file.
Always set up appropriate include guards or pragmas to avoid multiple inclusion. They're critical for this to work correctly.
The PCH master-header is not to be included in your header files. When designing your headers, do so with the intent that everything needed (and only that which is needed) by the header to compile is included. If an including source file needs additional includes for its implementation, it can pull them in as needed after your header.
The following is an example of how I would setup a project that uses multiple standard headers in both the .h and .cpp files.
myobject.h
#ifndef MYAPP_MYOBJECT_H
#define MYAPP_MYOBJECT_H
// we're using std::map and std::string here, so..
#include <map>
#include <string>
class MyObject
{
// some code
private:
std::map<std::string, unsigned int> mymap;
};
#endif
Note the above header should compile in whatever .cpp it is included, with or without PCH being used. On to the source file...
myobject.cpp
// apart from myobject.h, we also need some other standard stuff...
#include "myobject.h"
#include <iostream>
#include <fstream>
#include <algorithm>
#include <numeric>
// code, etc...
Note myobject.h does not expect you to include something it relies on. It isn't using <iostream> or <algorithm>, etc. in the header; we're using it here.
That is a typical setup with no PCH. Now we add the PCH master
Adding the PCH Master Header
So how do we set up the PCH master-header to turbo-charge this thing? For the sake of this answer, I'm only dealing with pulling in standard headers and 3rd-party library headers that will not undergo change with the project development. You're not going to be editing <map> or <iostream> (and if you are, get your head examined). Anyway...
See this answer for how a PCH is typically configured in Visual Studio. It shows how one file (usually stdafx.cpp) is responsible for generating the PCH, the rest of your source files then use said-PCH by including stdafx.h.
Decide what goes in the PCH. As a general rule, that is how your PCH should be configured. Put non-volatile stuff in there, and leave the rest for the regular source includes. We're using a number of system headers, and those are going to be our choices for our PCH master.
Ensure each source file participating in the PCH turbo-mode is including the PCH master-header first, as described in the linked answer from (1).
So, first, the PCH master header:
stdafx.h
#ifndef MYAPP_STDAFX_H
#define MYAPP_STDAFX_H
// MS has other stuff here. keep what is needed
#include <algorithm>
#include <numeric>
#include <iostream>
#include <fstream>
#include <map>
#include <string>
#endif
Finally, the source files configured to use this then do this. The minimal change needed is:
UPDATED: myobject.cpp
#include "stdafx.h" // <=== only addition
#include "myobject.h"
#include <iostream>
#include <fstream>
#include <algorithm>
#include <numeric>
// code, etc...
Note I said minimal. In reality, none of those standard headers need appear in the .cpp anymore, as the PCH master is pulling them in. In other words, you can do this:
UPDATED: myobject.cpp
#include "stdafx.h"
#include "myobject.h"
// code, etc...
Whether you choose to or not is up to you. I prefer to keep them. Yes, it can lengthen the preprocessor phase for the source file as it pulls in the headers, runs into the include-guards, and throws everything away until the final #endif. If your platform supports #pragma once (and VS does) that becomes a near no-op.
But make no mistake: The most important part of all of this is the header myobject.h was not changed at all, and does not include, or know about, the PCH master header. It shouldn't have to, and should not be built so it has to.
Precompiled headers are a method to shorten the build time. The idea is that the compiler could "precompile" declarations and definitions in the header and not have to parse them again.
With the speed of todays computers, the precompilation is only significant for huge projects. These are projects with a minimum of over 50k lines of code. The definition of "signification" is usually tens of minutes to build.
There are many issues surrounding Microsoft's stdafx.h. In my experience, the effort and time spent with discovering and resolving the issues, makes this feature more of a hassle for smaller project sizes. I have my build set up so most of the time, I am compiling only a few files; the files that don't change are not compiled. Thus, I don't see any huge impact or benefit to the precompiled header.
When using the precompiled header feature, every .cpp file must begin by including the stdafx.h header. If it does not, a compiler error results. So there is no point in putting the include in some header file. That header file cannot be included unless the stdafx.h has already been included first.