1

I have a Visual Studio 2017 C++ project which uses precompiled headers (stdafx.h).

My (simplified) file structure is as follows:

header1.hpp
header2.hpp
stdafx.h -> includes header1.hpp
code1.cpp -> includes stdafx.h
code2.cpp -> includes stdafx.h and header2.hpp

To avoid any ambiguity, by saying includes header1.hpp, I mean there is a line #include <header1.hpp> in the file.

  1. After I modify stdafx.h, all three files stdafx.h, code1.cpp and code2.cpp are recompiled (as expected).

  2. After I modify code1.cpp, only code1.cpp is recompiled (as expected).

  3. After I modify header2.cpp, all three files stdafx.h, code1.cpp and code2.cpp are recompiled (not expected!).

I would have expected item 3 to compile only code2.cpp, and not everything else.

A possible reason for this behavior would be that the build manager can't inspect and follow #include directives, so it simply recompiles everything if any header file is modified.

Since my project is quite large, recompiling all the files like code1.cpp takes up a significant amount of time. I purposely did not include header2.hpp from stdafx.h because I know I would modify header2.hpp often and only code2.cpp needs to use it. (header2.hpp is a template library that has functions only code2.cpp needs.)

Is this behavior expected, and what can I do to get Visual Studio to recognize that the other files need not be recompiled?

Bernard
  • 5,209
  • 1
  • 34
  • 64
  • That seems like expected behavior - Precompiled headers are meant to be recompiled whenever a header changes. –  Nov 03 '17 at 16:08
  • Is there any way to tell Visual Studio not to recompile the precompiled headers then? – Bernard Nov 03 '17 at 16:11
  • Simple - don't use precompiled headers. –  Nov 03 '17 at 16:13
  • In what order does code2.cpp include stdafx.h and header2.hpp? AFAIK, everything that comes before the `#include ` line is considered to be part of the precompiled headers. So header2.hpp should be included after. – Karsten Koop Nov 03 '17 at 16:13
  • @Thebluefish If I don't use precompiled headers then wouldn't all `.cpp` files still get compiled when I modify a header file? – Bernard Nov 03 '17 at 16:15
  • @KarstenKoop The first line of code2.cpp is `#include `. `#include ` is on the following line. – Bernard Nov 03 '17 at 16:17
  • The cpp files should only be recompiled if one of the header they `#include` get changed. –  Nov 03 '17 at 16:18
  • @Thebluefish I'll give that a try. But that means I'll have to sacrifice the speed boost of precompiled headers then. Also, if cpp files are only recompiled if one of their `#include`s gets changed then it means Visual Studio is smart enough to decipher include directives. In that case it seems inconsistent and strange that it doesn't decipher include directives for stdafx.h. – Bernard Nov 03 '17 at 16:26
  • The compiler never compiles a .h file, only ever a .cpp file. If that .cpp file #includes a .h file then you might see that happening, albeit that you did not tell us exactly how you saw that. One of the source files must have the /Yc compile option, it creates the .pch file so other .cpp files with /Yu can benefit from it. Normally that is stdafx.cpp with the default project settings. We can't see which of the .cpp files has that option, but it certainly sounds like it is code2.cpp. Not a good choice. – Hans Passant Nov 03 '17 at 16:27
  • @KarstenKoop Actually I think Visual Studio will refuse to compile the code if stdafx.h is not the first include directive. – Bernard Nov 03 '17 at 16:28
  • @HansPassant My stdafx.cpp is an empty file that is unused. There isn't anything special about code2.cpp. – Bernard Nov 03 '17 at 16:32
  • @HansPassant As I understand, all .h files are not compiled except stdafx.h. Isn't this correct? – Bernard Nov 03 '17 at 16:34
  • It is not correct, .h files get *included*, .cpp files get compiled. I have no real concept of how programmers might find an empty .cpp useful, consider following common practices so you can get help with your problems. And avoid them. – Hans Passant Nov 03 '17 at 16:38
  • Is `header2.hpp` included by another header? – 1201ProgramAlarm Nov 03 '17 at 17:20
  • @1201ProgramAlarm no it is not. – Bernard Nov 04 '17 at 02:06

1 Answers1

1

Turns out I had disabled precompiled headers a year ago (but left stdafx.h and stdafx.cpp in the project), and when I wanted to use them again I forgot to turn on the /Yc and Yu options.

No errors were given, and Visual Studio had been compiling stdafx.cpp like a regular .cpp file.

Also, I had the wrong idea of how precompiled headers worked. I thought stdafx.h gets compiled by itself (then dumped into those .cpp files that #include "stdafx.h" via some intermediate representation), but actually the file that gets compiled is stdafx.cpp (and while compiling produces the .pch file). (As per this question.)

After turning on the precompiled header options, when I modify header2.cpp, only code2.cpp gets recompiled, as I would like.

Also, compilation times are now significantly faster.

Bernard
  • 5,209
  • 1
  • 34
  • 64