Clang Modules 与 std <iterator> 和 <boost/move/iterator.hpp 的交互>



(有关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 <iterator>或在#include <boost/move/iterator.hpp>之后移动它,则错误消失。

问题:这仅仅是Boost库的副产品(显然,显然是Boost Move),没有为带有Clang Module Map Files的模块做好准备吗?这是模块映射文件现在已经为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>

使用中的版本

Boost 1.61

clang是从LLVM的Github镜像中的主分支的尖端,截至2016年12月7日(技术上是来自LLVM的叉子,但它仅在主分支上与LLVM自己的主人公有相同的位置):

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

我相信这是由libc 的模块的问题引起的,我昨天在R289028中修复了该模块。此错误导致启用模块时,LIBC 不会导出_LIBCPP_VERSION宏。

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

如果您重建llvm和libc ,应该解决您的问题。如果没有随意提交错误。

ps。看来我只是领先一步。

我目前只能以增强性1.59.1说话,但显然也可以假设只有在用clang构建时才能遇到libc :

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

在Mac OS X 10.9上引起了(几乎)完全相同的错误,该错误具有LIBC ,该LIBC 早于引入LIBC 回归,该回归引起了此线程中讨论的问题。

最新更新