← All guides

Build errors

C1010 and C1853 in MFC: Fix Precompiled Header Errors After Adding a .cpp or .c File

Published

You add two files from a small checksum library to an MFC dialog project: crc32.cpp and adler32.c. Neither file knows anything about MFC. The next build stops on the first one:

crc32.cpp(32,1): error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "pch.h"' to your source?

adler32.c fails with the same C1010. If you follow the message and add #include "pch.h" to the .c file, the error changes to C1853. Both errors come from a project setting that every added file inherits. Turning it off for those two files fixes both.

Every file in the project inherits the /Yu setting

An MFC project created by Visual Studio has a header named pch.h (stdafx.h in Visual Studio 2017 and earlier). It includes afxwin.h and the other MFC headers, so the compiler processes them once instead of once per .cpp file:

  • pch.cpp is compiled with Create (/Yc). It produces the precompiled header file, <project>.pch, in the intermediate folder.
  • The project itself is set to Use (/Yu) with pch.h. Every other source file inherits this, including any file you add later.

With /Yu"pch.h", the compiler does not start at the top of the file. It skips ahead to #include "pch.h", loads the .pch, and compiles only the code after that line (/Yu). crc32.cpp has no such line, so the compiler reaches the end of the file still looking for it. That is why the error points to line 32 of a 31-line file: the position is the end of the file, not a line with a mistake.

The header name in the message is the one set in the project’s Precompiled Header File property. In an older project the message names stdafx.h.

A .c file: C1010 first, then C1853

adler32.c without any change gives the same error at its end of file:

adler32.c(20,1): error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "pch.h"' to your source?

Adding #include "pch.h" above the other #include in adler32.c replaces it with this:

adler32.c(4,10): error C1853: 'x64\Debug\ChecksumToolCPch.pch' precompiled header file is from a different version of the compiler, or the precompiled header is C++ and you are using it from C (or vice versa)

The message gives two possible causes, and here it is the second one. A .c file is compiled as C, and the .pch was built from pch.cpp as C++. A single .pch cannot be used by both C and C++ sources (Precompiled header files). Rebuilding does not help, because the rebuilt .pch is C++ again.

Turn off precompiled headers for those files only

The rest of the project can keep using the precompiled header. Change the setting for the added files:

  1. In Solution Explorer, right-click crc32.cpp and choose Properties.
  2. Set Configuration to All Configurations and Platform to All Platforms. A setting made only for Debug leaves Release with the same error.
  3. Go to Configuration Properties > C/C++ > Precompiled Headers.
  4. Set Precompiled Header to Not Using Precompiled Headers, and choose OK.
  5. Do the same for adler32.c, and remove the #include "pch.h" line if you added it. pch.h brings in the MFC headers, which are C++.

In the .vcxproj file, the setting is a PrecompiledHeader element on that file’s ClCompile item. Without a Condition attribute, it applies to every configuration:

<ClCompile Include="..\third_party\crc32.cpp">
  <PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\third_party\adler32.c">
  <PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>

With these two items, the project compiles both files and links. The library code stays as it was downloaded.

You could make crc32.cpp compile by adding #include "pch.h" to it, but then the library file depends on your project’s header. You have to add the line again each time you update the library, and the file no longer compiles in a project that has no pch.h. For a .c file it is not an option at all, as the C1853 above shows.

In your own .cpp file, pch.h must be the first include

For a file that belongs to your project, keep /Yu and include pch.h first. Anything before it is skipped. This file includes the library header first:

// HexFormat.cpp
#include "crc32.h"
#include "pch.h"
#include "HexFormat.h"

CString FormatCrc32(const CStringA& sUtf8)
{
	CString sCrc;
	sCrc.Format(_T("%08X"), Crc32(sUtf8.GetString(), static_cast<size_t>(sUtf8.GetLength())));
	return sCrc;
}

There is no C1010, because #include "pch.h" is found. But crc32.h was never read, so the call fails:

HexFormat.cpp(9,26): error C3861: 'Crc32': identifier not found

Moving #include "pch.h" above #include "crc32.h" fixes it. If a function or type is reported as undeclared even though its header is clearly included, check whether that #include comes before pch.h.

C1853 on a .cpp file

If C1853 appears on a .cpp file compiled as C++ (the default for the extension), the C/C++ mismatch does not apply, and the first cause in the message is the likely one: the .pch in the intermediate folder was built by a different compiler version. This can happen after a Visual Studio update when old build output is still there. Build > Rebuild Solution creates the .pch again with the current compiler (C1853).

References