Why is C++Builder failing to create pre-compiled headers? - c++

Problem
In CodeGear C++Builder 2009 we are using the pre-compiled header injection to greatly reduce our compile times. We have the same header file being injected into multiple projects. When compiling some projects, the compiler kicks out the following warning:
[BCC32 Warning] Dateutils.hpp(43): W8058 Cannot create pre-compiled header: initialized data in header
In this example, the Dateutils.hpp is the file it's complaining about (CodeGear's header). I've seen this happen with other headers as well. What makes this interesting is that this only happens with some projects (same header being injected).
In the past, I've had to just find the header who ultimately included this errant file and remove it from my pre-compiled header file. Does anyone know what's going on here and the best way to fix it?
Update
I ended up performing a process of elimination approach to the header file and came up with an interesting finding that I cannot explain. Out of the 50+ headers that get included, when I removed vcl.h I no longer get the W8058 warnings. I do not understand this as I would imagine that this header file in particular is a prime candidate for pre-compiliation. Can anyone explain that?

One thing that may be related is the way default string parameters are handled by BCB 200x.
Functions declared like this give the "can't generate precompiled header" message.
void myFunc(const AnsiString &param="");
However, change it to this, and the precompiled header can be generated.
void myFunc(const AnsiString &param = AnsiString(""));

In my experience, that warning message is misleading. It seems that the compiler identifies "candidates" where a header might have initialized data, then when it determines that the file is actually ok, it goes on. If it doesn't find another candidate, it won't show the message. If it finds another candidate that turns out to be a real problem, it then shows the message about the first candidate.
This makes identifying the real culprit extremely difficult.

There are VCL header files that have this known issue: QC 23002. The marked severity on this item though is a "minor failure."
So the workaround options are limited:
Not using those header files (which, yes, does defeat the idea)
Modify the header files (not advisable -- hard to track changes, keep them current).
Either way, make sure that of the ones you come across, CodeGear has knowledge of those header files having that issue. That will certainly be the best way to address it long term -- let the vendor fix their problem. Supposedly CodeGear has DateUtils.hpp in their internal tests for this, but that was posted (for QC 2781) in July 2007. If the problem or certain header files affect you considerably, contact them about it.

I get this warning message when the code shows:
#include <vcl.h>
#pragma hdrstop
I found a simple fix by swapping these lines to:
#pragma hdrstop
#include <vcl.h>
Warning no longer appears.

Related

About updating C++ header files

This question is about something that after more than a year with C++ I can't solve or find any solution about it.
I got used to using separate files for headers and code in C, but I have a problem with it on C++: whenever I edit a header file and try to compile the code that uses it again, the compiler doesn't notice the change on the header.
What I do to solve this is "compiling" the header (.hpp) alone. Sometimes I just add it to the list of source files for g++ along with the rest of the code, but what happens then is that I have to execute the command twice (the first time it gives me errors, but not the second time). It also warns me that I'm using the "pragma once" option in a main file.
I know this is very wrong, so I've searched for a correct way to do this, without success. I have noticed that g++ generates ".gch" files but I don't really know what's their purpose, although they may be related.
I suspect that the problem is caused because of the code in the ".hpp". I know (I think) that the good way to do it is to define prototypes only inside the header and writing the body of the methods in a separate file, but sometimes (specially when using templates) this generates even more problems.
The .gch is a precompiled header and it is created if you explicitly compile a header file.
The compiler will then use that file instead of the actual header (the compiler does not care about modification timestamps).
Do rm *.gch and leave all headers out of the compilation command forever.
(And don't put template implementations in .cpp files.)

Find out what #define statements conflict between .h files

I'm in VS2013, C++ console applications. I'm having a problem integrating boost into a large framework. If I try integrating them in a blank console application, they work fine. Once I include the "root" .h file of the framework (that includes "many" other .h files in the bargain), it breaks. These .h files are "polluting" the boost ones (and anything included after, with mixed results, and no, I can't just include boost ones first, that's not always an option unfortunately). I've found at least one root-level #define that interfered and caused a compile error, but I can't find some of the other conflicts that are causing run-time problems.
Specifically, my problem is this: how do I tell what symbols have been defined by .h files? And hopefully, which ones are then conflicting later? I tried googling, but couldn't find a tool for doing this.
Or is there some other method which can "isolate" them (my problem .h files), and yet still have them link correctly to the functions they're calling in other .dlls?
You can use g++ -E as a static code checking tool (without changing your toolset). It is able to tell you when something is redefined but not when a #define is used as another name (it would have no way to tell whether it was a real substitution or not).
If that's not the source of your problem then you may need to take a more holistic approach: Start changing your project's #define use to other constructs such as const and short functions. This will then allow the compiler to either resolve differences by overloading or complain that there are conflicts.
Including same header file again might have caused the problem,you can create a symbol for each header file so that if that header file is already included in some other header file it shouldn't be included.
#ifndef
#define __header_file_name_H
.....some code
#endif

#include being ignored

So,
I've got this code I'm trying to update. It was written for visual studio 6, and I'm trying to get it to compile in visual studio 2010.
In stdafx.h, it includes afx.h and afxwin.h and a few other things necessary for the program to work. Notably, there's usage of CString in other header files.
At the top of the includes in stdafx.h, I added in a #pragma message, to verify that it was being compiled first. There's one at the top of the header file which throws the error, as well. I can see from the compiler output that stdafx.h was being compiled first, so that's good.
However, there was the error. (CString wasn't being recognized as a type.) So, I decided to make sure that it got through all of the includes. So, I put another #pragma message after #include and that message is not printed.
Does that mean is not actually being included?
Your explanation is a little hard to follow, but I think you're running into the differences between normal compilation and pre-compiled headers.
With pre-compiled headers, the compiler processes the first file normally (the new project wizard sets up stdafx.cpp for this). After processing the include file (typically stdafx.h) set in project options for pre-compilation control, the compiler saves its state to a .pch file.
For every other file, the compiler skims over the file without any processing, just looking for the include file. Then it reads the .pch file, loads the saved state, and continues parsing and compiling normally.
One consequence of this design is that any lines above #include "stdafx.h" in stdafx.cpp become part of the state and are seen by all other files. And lines above #include "stdafx.h" in other files are simply ignored.
Passing my comment to an answer.
CString in VS 6 times was a class and it changed afterwards to be a template. Maybe it has something to due with that?
The problem had to do with using
typedef with CString. Post VS 6,
that's not possible. I just changed
references by hand, and it compiles
now.
The problem had to do with using typedef with CString. Post VS 6, that's not possible. I just changed references by hand, and it compiles now.

Detecting precompiled headers

Is there a way for the preprocessor to detect if the code in current
translation unit uses(or is creating) precompiled headers?
---
The actual problem I'm facing right now is that I'm on a project that is
abusing PCH by precompiling virtually all header files. That means there is none of
the clear dependency management you can get from #includes and the compile times is awful.
Practically every change will trigger a full rebuild.
The application is way to big to just fix it in one go, and some of the old guys refuses
to belive that precompiling everyting is bad in any way. I will have to prove it first.
So I must do it step by step and make sure my changes does not affect
code that is compiled the old PCH way.
My plan is to do ifdef out the PCH.h and work on the non PCH version whenever I have some time to spare.
#ifdef USES_PCH
#include "PCH.h"
#elif
// include only whats needed
#endif
I would like to avoid defining USES_PCH at command line and manually keep it in
sync with /Y that, besides from not being very elegant, would be a pain. There is a lot of configurations
and modules to juggle with and a lot of files that don't follow project defaults.
If Visual C++ defined a constant to indicate whether precompiled headers were in use, it would probably be listed in Predefined Macros. And it's not documented there, so it probably doesn't exist. (If it does exist, it's probably undocumented and may change in a future version.)
This will not work, when using precompiled headers in Visual C++, you cannot even have any code before including a precompiled header. I was trying to do something similar, when I came across your question. After a little trial and error, I have found that there can be no code prior to the #include directive for the precompiled header when using the /Yu compiler option.
#ifdef USES_PCH
#include "stdafx.h"
#endif
result: fatal error C1020: unexpected #endif
As far as I know, it can't, but there are some heuristics: VC++ uses StdAfx.h, Borland uses #pragma hdrstop, etc.

How should I detect unnecessary #include files in a large C++ project?

I am working on a large C++ project in Visual Studio 2008, and there are a lot of files with unnecessary #include directives. Sometimes the #includes are just artifacts and everything will compile fine with them removed, and in other cases classes could be forward declared and the #include could be moved to the .cpp file. Are there any good tools for detecting both of these cases?
While it won't reveal unneeded include files, Visual studio has a setting /showIncludes (right click on a .cpp file, Properties->C/C++->Advanced) that will output a tree of all included files at compile time. This can help in identifying files that shouldn't need to be included.
You can also take a look at the pimpl idiom to let you get away with fewer header file dependencies to make it easier to see the cruft that you can remove.
PC Lint works quite well for this, and it finds all sorts of other goofy problems for you too. It has command line options that can be used to create External Tools in Visual Studio, but I've found that the Visual Lint addin is easier to work with. Even the free version of Visual Lint helps. But give PC-Lint a shot. Configuring it so it doesn't give you too many warnings takes a bit of time, but you'll be amazed at what it turns up.
There's a new Clang-based tool, include-what-you-use, that aims to do this.
!!DISCLAIMER!! I work on a commercial static analysis tool (not PC Lint). !!DISCLAIMER!!
There are several issues with a simple non parsing approach:
1) Overload Sets:
It's possible that an overloaded function has declarations that come from different files. It might be that removing one header file results in a different overload being chosen rather than a compile error! The result will be a silent change in semantics that may be very difficult to track down afterwards.
2) Template specializations:
Similar to the overload example, if you have partial or explicit specializations for a template you want them all to be visible when the template is used. It might be that specializations for the primary template are in different header files. Removing the header with the specialization will not cause a compile error, but may result in undefined behaviour if that specialization would have been selected. (See: Visibility of template specialization of C++ function)
As pointed out by 'msalters', performing a full analysis of the code also allows for analysis of class usage. By checking how a class is used though a specific path of files, it is possible that the definition of the class (and therefore all of its dependnecies) can be removed completely or at least moved to a level closer to the main source in the include tree.
I don't know of any such tools, and I have thought about writing one in the past, but it turns out that this is a difficult problem to solve.
Say your source file includes a.h and b.h; a.h contains #define USE_FEATURE_X and b.h uses #ifdef USE_FEATURE_X. If #include "a.h" is commented out, your file may still compile, but may not do what you expect. Detecting this programatically is non-trivial.
Whatever tool does this would need to know your build environment as well. If a.h looks like:
#if defined( WINNT )
#define USE_FEATURE_X
#endif
Then USE_FEATURE_X is only defined if WINNT is defined, so the tool would need to know what directives are generated by the compiler itself as well as which ones are specified in the compile command rather than in a header file.
Like Timmermans, I'm not familiar with any tools for this. But I have known programmers who wrote a Perl (or Python) script to try commenting out each include line one at a time and then compile each file.
It appears that now Eric Raymond has a tool for this.
Google's cpplint.py has an "include what you use" rule (among many others), but as far as I can tell, no "include only what you use." Even so, it can be useful.
If you're interested in this topic in general, you might want to check out Lakos' Large Scale C++ Software Design. It's a bit dated, but goes into lots of "physical design" issues like finding the absolute minimum of headers that need to be included. I haven't really seen this sort of thing discussed anywhere else.
Give Include Manager a try. It integrates easily in Visual Studio and visualizes your include paths which helps you to find unnecessary stuff.
Internally it uses Graphviz but there are many more cool features. And although it is a commercial product it has a very low price.
You can build an include graph using C/C++ Include File Dependencies Watcher, and find unneeded includes visually.
If your header files generally start with
#ifndef __SOMEHEADER_H__
#define __SOMEHEADER_H__
// header contents
#endif
(as opposed to using #pragma once) you could change that to:
#ifndef __SOMEHEADER_H__
#define __SOMEHEADER_H__
// header contents
#else
#pragma message("Someheader.h superfluously included")
#endif
And since the compiler outputs the name of the cpp file being compiled, that would let you know at least which cpp file is causing the header to be brought in multiple times.
PC-Lint can indeed do this. One easy way to do this is to configure it to detect just unused include files and ignore all other issues. This is pretty straightforward - to enable just message 766 ("Header file not used in module"), just include the options -w0 +e766 on the command line.
The same approach can also be used with related messages such as 964 ("Header file not directly used in module") and 966 ("Indirectly included header file not used in module").
FWIW I wrote about this in more detail in a blog post last week at http://www.riverblade.co.uk/blog.php?archive=2008_09_01_archive.xml#3575027665614976318.
Adding one or both of the following #defines
will exclude often unnecessary header files and
may substantially improve
compile times especially if the code that is not using Windows API functions.
#define WIN32_LEAN_AND_MEAN
#define VC_EXTRALEAN
See http://support.microsoft.com/kb/166474
If you are looking to remove unnecessary #include files in order to decrease build times, your time and money might be better spent parallelizing your build process using cl.exe /MP, make -j, Xoreax IncrediBuild, distcc/icecream, etc.
Of course, if you already have a parallel build process and you're still trying to speed it up, then by all means clean up your #include directives and remove those unnecessary dependencies.
Start with each include file, and ensure that each include file only includes what is necessary to compile itself. Any include files that are then missing for the C++ files, can be added to the C++ files themselves.
For each include and source file, comment out each include file one at a time and see if it compiles.
It is also a good idea to sort the include files alphabetically, and where this is not possible, add a comment.
If you aren't already, using a precompiled header to include everything that you're not going to change (platform headers, external SDK headers, or static already completed pieces of your project) will make a huge difference in build times.
http://msdn.microsoft.com/en-us/library/szfdksca(VS.71).aspx
Also, although it may be too late for your project, organizing your project into sections and not lumping all local headers to one big main header is a good practice, although it takes a little extra work.
If you would work with Eclipse CDT you could try out http://includator.com to optimize your include structure. However, Includator might not know enough about VC++'s predefined includes and setting up CDT to use VC++ with correct includes is not built into CDT yet.
The latest Jetbrains IDE, CLion, automatically shows (in gray) the includes that are not used in the current file.
It is also possible to have the list of all the unused includes (and also functions, methods, etc...) from the IDE.
Some of the existing answers state that it's hard. That's indeed true, because you need a full compiler to detect the cases in which a forward declaration would be appropriate. You cant parse C++ without knowing what the symbols mean; the grammar is simply too ambiguous for that. You must know whether a certain name names a class (could be forward-declared) or a variable (can't). Also, you need to be namespace-aware.
Maybe a little late, but I once found a WebKit perl script that did just what you wanted. It'll need some adapting I believe (I'm not well versed in perl), but it should do the trick:
http://trac.webkit.org/browser/branches/old/safari-3-2-branch/WebKitTools/Scripts/find-extra-includes
(this is an old branch because trunk doesn't have the file anymore)
If there's a particular header that you think isn't needed anymore (say
string.h), you can comment out that include then put this below all the
includes:
#ifdef _STRING_H_
# error string.h is included indirectly
#endif
Of course your interface headers might use a different #define convention
to record their inclusion in CPP memory. Or no convention, in which case
this approach won't work.
Then rebuild. There are three possibilities:
It builds ok. string.h wasn't compile-critical, and the include for it
can be removed.
The #error trips. string.g was included indirectly somehow
You still don't know if string.h is required. If it is required, you
should directly #include it (see below).
You get some other compilation error. string.h was needed and isn't being
included indirectly, so the include was correct to begin with.
Note that depending on indirect inclusion when your .h or .c directly uses
another .h is almost certainly a bug: you are in effect promising that your
code will only require that header as long as some other header you're using
requires it, which probably isn't what you meant.
The caveats mentioned in other answers about headers that modify behavior
rather that declaring things which cause build failures apply here as well.