拉了个2010年的VC工程,编译第一条就报C1010,说在查找预编译头时意外遇到文件结尾。翻遍源码没看出语法问题,实际原因是某个cpp把#include stdafx.h写在了第二行,前面还夹了一句注释。

这个文件到底干什么

stdafx是standard application framework extensions的缩写,文件本身没有任何魔法,作用是把windows.h、tchar.h、afxwin.h这些几乎每个cpp都要用的头文件集中起来预编译一次,生成同名的.pch文件。之后每个cpp编译时直接加载.pch,省掉重复解析头文件的时间。工程一大,能省掉一半以上的编译时间,这也是它存在的唯一理由。

三个设置必须配套

项目属性里,C/C++的预编译头选使用,指定头文件名stdafx.h;同时工程里必须有一个cpp把它设成创建,默认这个文件叫stdafx.cpp,内容只有一行include。三者对不上就是C1010,或者C1853,后者提示预编译头文件来自以前的编译器版本,把Debug目录下的.pch删掉重编即可。

每个cpp的第一行必须是它

#include stdafx.h  #include 自己的头文件

顺序不能反,前面也不能有任何代码,连注释都建议放到后面,老版本编译器对注释位置也敏感。常见错误是把include包进#ifndef里,条件不成立时预编译头就没生效。确实不想用的,属性里改成不使用预编译头,代价是全量编译慢,几十个cpp的工程能差出好几分钟。

VS2017之后它改名了

新版本向导生成的项目里叫pch.h,stdafx.h只是历史叫法。老工程升级上来继续用stdafx.h完全没问题,名字是任意的,关键是设置里指向同一个文件。从GitHub拉的项目报找不到stdafx.h,先看属性里预编译头指向哪个名字,再看文件是不是被.gitignore漏掉了,这两步能解决九成情况。

  • 别往里塞业务代码:改一行会触发全工程重编,编译时间直接翻倍。
  • 别放using namespace:会污染所有cpp,报错信息里全是命名空间冲突,没法看。
  • 第三方库的头文件:放进去之前确认它不会随版本变,否则每次升级都要全量重编。