【问题标题】:Why does the preprocessor skip a file based on its "modifed date"?为什么预处理器会根据“修改日期”跳过文件?
【发布时间】:2013-10-08 18:44:26
【问题描述】:

这是我能做的最简单的例子来说明我遇到的问题。

我们的文件结构如下:

.
├── main.cpp
├── root
│   ├── A
│   │   └── same.hpp
│   ├── A.hpp
│   ├── B
│   │   └── same.hpp
│   └── B.hpp
└── root.hpp

ma​​in.cpp:

#include "root.hpp"
int main(){}

root.hpp:

#pragma once
namespace root{
    #include "root/A.hpp"
    using namespace A;

    #include "root/B.hpp"
    using namespace B;
}

A.hpp:

#pragma once
namespace A{
    #include "A/same.hpp"
    using namespace same;
}

B.hpp:

#pragma once
namespace B{
    #include "B/same.hpp"
    using namespace same;
}

两个相同的.hpp 文件:

#pragma once
namespace same{}

在 main.cpp 预处理之后,我们期望源代码是:

namespace root{
    namespace A{
        namespace same{}
        using namespace same;
    }
    using namespace A;

    namespace B{
        namespace same{}
        using namespace same;
    }
    using namespace B;
}
int main(){}

但是,运行g++ -std=c++11 -P -E main.cpp 后的实际输出缺少“相同”命名空间的第二次减速:

namespace root{
    namespace A{
        namespace same{}
        using namespace same;
    }
    using namespace A;

    namespace B{
        //...      <- where did it go?
        using namespace same;
    }
    using namespace B;
}
int main(){}

更有趣的是,当我在 B 的 same.hpp 文件上运行 touch 命令并在 main.cpp 上重新运行该命令时,它按预期工作(因为输出与我们最初的匹配预期的)。这让我相信文件被跳过的原因与修改日期有关。
关于为什么会发生这种情况的任何见解?

【问题讨论】:

  • 我记得看到一些关于#pragma once 的内容,它使用文件名来确定是否应该跳过它,这样就可以解释为什么该行丢失了。不过,我不知道修改日期是如何影响它的。我会尝试使用包含警卫,并为您的 A/same.hppB/same.hpp 文件使用单独的符号。
  • 我的钱是你的#pragma once 使用的是文件名而不是路径名,因此被两个同名的文件所欺骗。
  • 在许多现代文件系统上,A/same.hppB/same.hpp 可能是同一个文件的两个名称。编译器要做什么?
  • @MSalters 检查它们是否具有相同的 inode,或者检查它们是否是符号/硬链接?我想你是对的。如果只是解析文本,它不知道回避问题。

标签: c++ namespaces include g++ c-preprocessor


【解决方案1】:

问题已通过在外观相似的文件中输出独特的评论得到解决。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多