繁体   English   中英

MSVC ++ 2008 Express Editon编译器的功能和功能

[英]What MSVC++ 2008 Express Editon compiler does and doesn't

我一直想知道msvc ++ 2008编译器是否负责同一文件的多个头包含,考虑这个例子:
main.cpp中

#include "header.h"
#include "header.h"

编译器会多次包含此文件还是只包含一个文件? (我知道我可以使用#ifndef“技巧”来防止这种情况发生)另外,如果我包含“header.h”,其中包含10个函数,但我只调用或使用2,它是否仍然包含所有10个或者只是我需要的2和他们所有的需求?

#include基本上是“复制粘贴”的同义词。 如果您执行相同的#include ,则该头文件的内容将按顺序复制和粘贴两次。

至于你的第二个问题,它确实没有意义。 #include预处理器执行, 预处理器编译器链接器之前运行。 预处理器不知道或不关心头文件的内容是什么,它只是将其复制并粘贴。链接器可能能够消除不必要的功能,但这完全独立于预处理器。

不,编译器(或者更准确地说,预处理器)不会“自动”处理这个问题。 不在Visual C ++ 2008或任何其他版本中。 而你真的不希望它。

有两种标准的方法可以解决这个问题。 你应该选择其中一个。

第一种被称为包括警卫 那是你在问题中提到的“ #ifndef技巧”。 但它肯定不是一个“技巧”。 这是编写C ++代码时处理这种情况的标准习惯用法,而任何其他查看源文件的程序员几乎肯定在某处看到包含警卫。

另一个利用VC ++功能(也可以用于其他几个C ++工具包),以一种更容易键入的方式完成相同的操作。 通过在头文件的顶部包含一行#pragma once ,您可以指示预处理器每个翻译单元只包含一次头文件。 除了包括警卫外,这还有一些其他优点 ,但它们在这里并不特别重要。

至于你的第二个问题, 链接器将负责“优化”你从未在代码中调用的函数。 但这是编译的最后阶段,与预处理器处理的#include无关,正如我上面提到的那样。

MSVC 20xx预处理器(不是编译器 - 编译器从未看到预处理器指令)在任何意义上都没有“处理”同一文件的多个#includes。 如果文件是#included两次,则预处理器服从#includes并包含该文件两次。 (想象一下,如果预处理器甚至考虑尝试纠正源文件的“坏”#include行为,那么混乱。)

由于预处理器在遵循您的指示时非常谨慎和谨慎,因此每个#included文件必须保护自己不被#included两次。 当我们在头文件的顶部找到这样的行时,我们会看到这种保护:

 #ifndef I_WAS_ALREADY_INCLUDED   // if not defined, continue with include
 #define I_WAS_ALREADY_INCLUDED   // but make sure I'm not included again

    [ header-file real contents ]

 #endif  // I_WAS_ALREADY_INCLUDED

编写头文件时,必须始终确保以这种方式保护它。

你为什么在乎? 它不会给编译器增加太多负担,因为编译器有条件地(例如#ifdef s)会排除它不需要编译的代码。

预处理器将包含2次这些标头。 这就是为什么头文件中的警卫是必需的。 据我所知,链接器大多数情况下会删除较新的用于减少可执行文件大小的代码(函数)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM