包括顺序和隐藏的依赖项

时间:2017-05-30 08:49:56

标签: c++ include dependencies

在寻找有关包含订单的最佳实践时,我在这个问题上遇到了磕磕绊:

C/C++ include file order/best practices [closed]

@squelart表示,从本地到全局包含更好的实践,因为这减少了隐藏依赖的机会。我刚刚在VS2015项目中使用以下代码对此进行了测试:

StrTest.h

#pragma once

class CStrTest
{
    public:
        CStrTest();
        ~CStrTest();

        std::string test;
};

StrTest.cpp

#include <string>
#include "StrTest.h"


CStrTest::CStrTest()
{
}

CStrTest::~CStrTest()
{
}

我无法重现所述行为(在StrTest.cpp中首先隐藏包含字符串的依赖关系)。编译器给了我很多错误。这是过去的事情还是我忽略了什么?

编辑:VS2015编译器错误:

错误C4430缺少类型说明符 - 假设为int。注意:C ++不支持default-int

错误C2039'string':不是'std'的成员

错误C3646'test':未知的覆盖说明符

2 个答案:

答案 0 :(得分:1)

  

这是过去的事情

不,隐藏的依赖项是标准行为,并且确实发生在现代编译器中。我不知道VS,但是GCC和Clang确实编译了你显示的程序而没有任何错误。演示:https://wandbox.org/permlink/ATJndwrOwirpDgDd

  

编译器给了我很多错误。

虽然“隐含”包含的风格很差,但就标准而言,它仍然在技术上很好地形成,只要隐含包含的文件保证包含在您或包含它的标题的任何人 - 标准标题没有这样的保证。

因此,我会反对将隐式包含为错误的编译器功能。明确启用警告会更合适。

答案 1 :(得分:0)

我认为那里讨论的隐藏依赖问题的一点是,通常每个文件都包含其他几个文件,如果标题不是自包含的,那么包含它可能适用于某些其他标题包含隐式依赖并破坏所有内容的情况当那些其他标题改变和/或被移动/移除时。简而言之:使用隐藏依赖项的标头会导致代码非常脆弱。

// foo.hpp
#pragma once

#include <string> // if we remove this unrelated `StrTest.h` header will be broken
...

// main.cpp

#include "foo.hpp" // if we move this one line lower `StrTest.h` header will be broken
#include "StrTest.h" // accidentally works fine
...