C ++编译器错误地解析头文件之前的源文件

时间:2016-07-20 11:43:20

标签: c++ visual-studio-2015

当我更改包含模板类定义的头文件时,我的编译器(VS2015附带的编译器)首先解析实例化类的源文件,然后才解析头文件。这导致二进制文件不正确。

但是,如果我再次更改头文件并进行编译,则解析顺序是正确的(首先是头,后面是源),并且生成的二进制文件可以正常工作。

编译器解析文件的顺序可以在Build输出窗口中看到,我没有启用并行或多处理器编译选项。

我可以100%的成功率重现这一点。我做错了什么,有什么我可以改变的吗?

代码如下。

Class.h

template<class T> class Class {
    void foo () {
        WriteToFile("A");
    }

Usage.cpp

Class* c = new C();
c->foo();

完全构建/重建。文件输出:A。

第1步:

将以下行添加到foo()WriteToFile("B"); 编译:输出顺序:Usage.cpp,Class.h 文件输出:A

第2步:

将以下行添加到foo()WriteToFile("C");` 编译:输出顺序:Class.h,Usage.cpp 文件输出:A B C

继续,直到永远,同样的行为。

注意:我只需按F7到&#34; Build&#34;,完全重建后它可以正常工作,但需要很长时间。

3 个答案:

答案 0 :(得分:0)

您的源文件(.cpp)仅被编译,并将包含的头文件(.h)中的代码复制到源文件中。   头文件不是独立编译的。

您可以从Build输出窗口复制日志。

答案 1 :(得分:0)

您发布的代码充满了错误,如果这是您正常代码的示例,则可能发生任何事情。

如上所述,你不应该看到h文件编译。如果您这样做,您可能已将其设置为编译为cpp文件或类似的东西。这是你应该看的第一个地方。

在预处理阶段将H文件添加到CPP文件中,生成长源文件,如果选择编译选项以保留它们,则可以读取这些文件。不知道它的顶端是什么。如果查看这些长文件,那么您将看到Class.h正在#include "Class.h"语句发生时添加到Usage.cpp中。除非你包含旧版本的Class.h,否则很难看出你所描述的内容可能会发生。除非您使用预编译的头文件,并且您的class.h文件是PCH的一部分,并且您使用的是陈旧的PCH文件。

如果你每次都使用重建,而不是构建(F7),我怀疑问题会消失。我怀疑这是因为PCH生成问题所以请检查stdafx.cpp是否设置为重新生成PCH。

答案 2 :(得分:0)

固定。在Visual Studio解决方案资源管理器中右键单击该文件 - &gt;属性 - &gt;物品种类。对于该特定头文件,它被设置为C / C ++编译器。将其更改为C / C ++标题后,它就可以了。

我认为这是因为当我向解决方案添加新文件时,我右键单击过滤器 - &gt;添加新项目。如果选择了Source文件,我没有把它更改为Header文件,我只想命名文件SomeName.h。它似乎有所作为。基于此,.vcxproj将包含一个以<ClInclude><ClCompile>

开头的文件行