什么是Visual Studio中使用的"stdafx.h"?

pro*_*eek 488 cross-platform visual-studio-2010 stdafx.h visual-studio visual-c++

stdafx.h我在Visual Studio 2010中启动项目时会自动生成一个名为的文件.我需要创建一个跨平台的C++库,所以我不能/不能使用这个头文件.

什么stdafx.h用于?我可以删除这个头文件吗?

Eur*_*lli 807

所有C++编译器都有一个严重的性能问题需要处理.编译C++代码是一个漫长而缓慢的过程.

编译包含在C++文件之上的标头是一个非常漫长而缓慢的过程.编译形成的Windows API和其他大型API库的一部分的巨大的头结构是一个非常,非常长的,缓慢的过程.对于每一个Cpp源文件来说,必须完成它,并且结束和结束是一个致命的丧钟.

这不是Windows独有的,但是所有必须针对像Windows这样的大型API编译的编译器所面临的老问题.

Microsoft编译器可以通过称为预编译头的简单技巧来改善此问题.诀窍很漂亮:虽然每个CPP文件都可以在法律上给每个Cpp文件顶部包含的头文件链带来一些不同的含义(通过使用不同的宏#include在包含之前定义,或者通过以不同的顺序包括标题),这通常不是这种情况.大多数情况下,我们有几十个或几百个包含的文件,但它们都与您的应用程序中编译的所有Cpp文件具有相同的含义.

如果编译器不必每次都从头开始编译每个Cpp文件加上其中的几十个包含,那么编译器可以节省大量时间.

技巧包括指定一个特殊的头文件作为所有编译链的起点,即所谓的"预编译头"文件,它通常是一个名为stdafx.h的文件,仅仅是出于历史原因.

只需按照适当的顺序在stdafx.h文件中列出API的所有大标题,然后#include "stdafx.h"在任意有意义的内容之前用最好的内容启动每个CPP文件(之前允许的唯一内容是评论).

在这些条件下,编译器不是从头开始,而是从已经保存的编译所有内容的结果开始编译stdafx.h.

我不认为这个技巧是微软编译器独有的,我也不认为这是一个原创的开发.

对于Microsoft编译器,控制预编译头的使用的设置由编译器的命令行参数控制:/Yu "stdafx.h".可以想象,使用stdafx.h文件名只是一种约定; 如果您愿意,可以更改名称.

在Visual Studio 2010中,通过右键单击CPP项目,选择"属性"并导航到"配置属性\ C/C++ \预编译标题",从GUI控制此设置.对于其他版本的Visual Studio,GUI中的位置将不同.

请注意,如果您禁用预编译的标头(或通过不支持它们的工具运行您的项目),它不会使您的程序非法; 它只是意味着您的工具每次都会从头开始编译所有内容.

如果要创建没有Windows依赖项的库,则可以轻松地从stdafx.h文件中注释掉或删除#includes.无需删除文件本身,但显然您也可以通过禁用上面的预编译头设置来删除文件.

  • 历史的好奇心.stdafx.h的名称可以追溯到1992年左右,当时MFC在发布之前被称为"应用程序框架扩展".Visual Studio 2015仍默认为名称.. (23认同)
  • omg,非常好的答案确实.我正在寻找符合标准的c编译器.事实证明,我可以从项目属性中禁用micro $ oft扩展,将编译器从"auto"更改为"c",并且您几乎拥有"标准"编译器和IDE. (10认同)
  • 即使您只使用std命名空间中的文件,也可以获得速度优势 (6认同)
  • @Rishi:'line',你的意思是`#include"stdafx.h"`?当然,但这只是一个标准#include."MS扩展"部分只是编译器性能优化; 它不会改变具有恰好被称为"stdafx.h"的头文件的语义.请注意,如果删除include并且代码依赖于stdafx.h中包含的任何内容,则必须直接包含它. (4认同)
  • @ Youda008,不太正确.在编译代码文件之前,标题的内容简单地在字面上"粘贴"在源文件中"#include"它们的位置(由评估宏的相同"预处理器"步骤完成).然后将生成的总文件传递给实际的编译器,该编译器永远不会将头文件视为单独的实体.您只在头文件上放置声明,因为这在头文件上运行良好 - 这是一个传统的规则.试试吧!使用整个程序创建头文件,然后创建一个只有#include的源文件.它汇编很好. (4认同)
  • @ Youda008,当然,就像你输入两次代码一样.但我想我现在理解你的问题 - 让我再试一次:你通常不会*从头文件的内容中"发出代码",但是a)编译器在处理头文件之前不知道和b)编译C++要比将公式转换为机器代码(例如模板)复杂得多.即使没有发出代码,编译器仍然需要处理头并为其创建内部表示,因为它改变了编译源文件的方式.这对于复杂的标头来说非常昂贵. (3认同)

cas*_*nca 44

它是一个"预编译的头文件" - 您在stdafx.h中包含的任何头文件都经过预处理,以便在后续编译期间节省时间.您可以在MSDN上阅读更多相关信息.

如果您正在构建跨平台应用程序,请在创建项目时选中"清空项目",Visual Studio将不会在项目中放置任何文件.

  • 此文件中没有任何内容在其他平台上不起作用.如果编译器不支持预编译头,它可能会减慢那里的编译速度,但它不应该破坏它.它只是一个包含其他头文件的头文件. (15认同)
  • @detunized:也许我的答案听起来不错,所以谢谢你澄清那一部分. (2认同)

小智 5

“Stdafx.h”是一个预编译头。它包含标准系统包含文件和经常使用但不经常更改的项目特定包含文件的包含文件。这减少了编译时间和不必要的处理。

预编译头stdafx.h基本上在Microsoft Visual Studio中使用,让编译器知道曾经编译过的文件,而无需从头开始编译。您可以阅读更多相关内容

http://www.cplusplus.com/articles/1TUq5Di1/

https://learn.microsoft.com/en-us/cpp/ide/precompiled-header-files?view=vs-2017