【问题标题】:Clang Modules interaction with std <iterator> and <boost/move/iterator.hpp>Clang 模块与 std <iterator> 和 <boost/move/iterator.hpp> 的交互
【发布时间】:2016-12-08 23:56:54
【问题描述】:

(有关我正在使用的特定版本的 Boost 和 Clang 的信息,请参阅问题的结尾)

使用新的实验性 -fmodules 功能从 master/HEAD 在 Clang 中编译,使用如下所示的命令行选项编译以下文件时出现构建错误:

#include <iterator>
#include <boost/move/iterator.hpp>

编译命令和错误:

anhall@leviathan: <path-to-clang-install-from-master>/bin/clang++ -o file.o -c file.cpp --std=c++1z -stdlib=libc++ -fmodules

In file included from file.cpp:2:
In file included from /usr/local/include/boost/move/iterator.hpp:27:
/usr/local/include/boost/move/detail/iterator_traits.hpp:60:17: error: reference to 'random_access_iterator_tag' is ambiguous
   typedef std::random_access_iterator_tag   iterator_category;
                ^
/Users/anhall/impersonal/code/llvm-reflexpr/install/bin/../include/c++/v1/iterator:438:30: note: candidate found by name lookup is 'std::__1::random_access_iterator_tag'
struct _LIBCPP_TYPE_VIS_ONLY random_access_iterator_tag : public bidirectional_iterator_tag {};
                             ^
/usr/local/include/boost/move/detail/iterator_traits.hpp:34:8: note: candidate found by name lookup is 'std::random_access_iterator_tag'
struct random_access_iterator_tag;
       ^
/usr/local/include/boost/move/detail/iterator_traits.hpp:71:17: error: reference to 'random_access_iterator_tag' is ambiguous
   typedef std::random_access_iterator_tag   iterator_category;
                ^
/Users/anhall/impersonal/code/llvm-reflexpr/install/bin/../include/c++/v1/iterator:438:30: note: candidate found by name lookup is 'std::__1::random_access_iterator_tag'
struct _LIBCPP_TYPE_VIS_ONLY random_access_iterator_tag : public bidirectional_iterator_tag {};
                             ^
/usr/local/include/boost/move/detail/iterator_traits.hpp:34:8: note: candidate found by name lookup is 'std::random_access_iterator_tag'
struct random_access_iterator_tag;
       ^
In file included from file.cpp:2:
/usr/local/include/boost/move/iterator.hpp:196:17: error: reference to 'output_iterator_tag' is ambiguous
   typedef std::output_iterator_tag    iterator_category;
                ^
/Users/anhall/impersonal/code/llvm-reflexpr/install/bin/../include/c++/v1/iterator:435:30: note: candidate found by name lookup is 'std::__1::output_iterator_tag'
struct _LIBCPP_TYPE_VIS_ONLY output_iterator_tag {};
                             ^
/usr/local/include/boost/move/detail/iterator_traits.hpp:35:8: note: candidate found by name lookup is 'std::output_iterator_tag'
struct output_iterator_tag;
       ^
In file included from file.cpp:2:
/usr/local/include/boost/move/iterator.hpp:238:17: error: reference to 'output_iterator_tag' is ambiguous
   typedef std::output_iterator_tag    iterator_category;
                ^
/Users/anhall/impersonal/code/llvm-reflexpr/install/bin/../include/c++/v1/iterator:435:30: note: candidate found by name lookup is 'std::__1::output_iterator_tag'
struct _LIBCPP_TYPE_VIS_ONLY output_iterator_tag {};
                             ^
/usr/local/include/boost/move/detail/iterator_traits.hpp:35:8: note: candidate found by name lookup is 'std::output_iterator_tag'
struct output_iterator_tag;
       ^
In file included from file.cpp:2:
/usr/local/include/boost/move/iterator.hpp:278:17: error: reference to 'output_iterator_tag' is ambiguous
   typedef std::output_iterator_tag    iterator_category;
                ^
/Users/anhall/impersonal/code/llvm-reflexpr/install/bin/../include/c++/v1/iterator:435:30: note: candidate found by name lookup is 'std::__1::output_iterator_tag'
struct _LIBCPP_TYPE_VIS_ONLY output_iterator_tag {};
                             ^
/usr/local/include/boost/move/detail/iterator_traits.hpp:35:8: note: candidate found by name lookup is 'std::output_iterator_tag'
struct output_iterator_tag;
       ^
5 errors generated.

如果我删除 #include &lt;iterator&gt; 或将其移到 #include &lt;boost/move/iterator.hpp&gt; 之后,错误就会消失。

问题:这仅仅是 Boost 库(显然是 Boost Move)没有为具有 Clang 模块映射文件的模块准备的副产品吗?这可能是 Clang 现在为 libc++ 实现的模块映射文件的错误,甚至是模块实现本身的错误?

有趣的是,我可以通过注释掉 boost/move/detail/iterator_traits.hpp 的第 28-28 行来消除错误:

// #include <boost/move/detail/std_ns_begin.hpp>
// BOOST_MOVE_STD_NS_BEG
//
// struct input_iterator_tag;
// struct forward_iterator_tag;
// struct bidirectional_iterator_tag;
// struct random_access_iterator_tag;
// struct output_iterator_tag;
//
// BOOST_MOVE_STD_NS_END
// #include <boost/move/detail/std_ns_end.hpp>

正在使用的版本

提升 1.61

截至 2016 年 12 月 7 日,Clang 来自 LLVM 的 github 镜像中的 master 分支的尖端(技术上它来自 LLVM 的一个分支,但它仅在与 LLVM 自己的 master 分支相同的 master 分支上):

clang version 4.0.0 (https://github.com/matus-chochlik/clang.git b9cb1c8a1ebf52695372de12c7b04c8ef1bd8b4e) (https://github.com/llvm-mirror/llvm.git b60c7b1f61eabbe971d08568adb790a7cfc6a403)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Users/anhall/impersonal/code/llvm-reflexpr/install/bin

【问题讨论】:

  • 这似乎是 Clang 在尝试在模块中进行名称查找时忘记了命名空间限定符。或者至少这是我最好的猜测。这似乎不是 libc++ 中的错误,也不是模块映射。我会进一步调查。

标签: c++ boost clang++ c++17 c++-modules


【解决方案1】:

我认为这是由 libc++ 的 module.modulemap 问题引起的,我昨天在 r289028 中修复了该问题。此错误导致 _LIBCPP_VERSION 宏在启用模块时无法由 libc++ 导出。

查看boost/move/detail/iterator_traits.hpp 后,似乎如果_LIBCPP_VERSION 未定义,它将错过配置并最终声明完全不同的迭代器标签定义。 (具体来说,它将直接在命名空间std 中定义它们,而不是在 libc++ 的版本控制命名空间中)。

如果您重新构建 LLVM 和 libc++,它应该解决您的问题。如果没有,请随时file a bug

PS。看来我只是one step ahead

【讨论】:

  • 所以你在一个月前修复了一个我几天前遇到的错误,然后你修复了我昨天遇到的一个错误......希望它不是固定的线性对应,所以它不是另一个一个月,直到你修复我会在两天内找到的错误...... ;-)
  • 希望您不再遇到错误 :-) 但是在使用实验性功能时很可能会出现这种情况。
  • 感谢您对新修复的回答 - 我还没有机会更新我的 clang 源并尝试它,但我会在有机会时回来告诉您。跨度>
【解决方案2】:

目前我只能说 boost 1.59.1,但它显然也假设了 libc++ 只能在使用 clang 构建时遇到:

#if defined(__clang__) && defined(_LIBCPP_VERSION)
// ...
#else
// ...
#endif

即使在 Mac OS X 10.9 上,它也会引发(几乎)完全相同的错误,它的 libc++ 早于引入导致本线程中讨论的问题的 libc++ 回归。

【讨论】:

    猜你喜欢
    • 2016-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-18
    • 2023-01-11
    • 2015-05-03
    相关资源
    最近更新 更多