Botan编译错误VS2015

4
我这里有一个奇怪的情况。我想在VS2015中使用Botan加密库(因为项目的其他部分使用一些重的C++11代码,而VS2013无法编译),但我得到了一个相当长的编译错误(见下文)。
尝试了各种方法后,我得出结论,即使已经在编译的C++源文件中包含了botan头文件之一,编译器也会抛出下面的错误。现在我的文件中只有一行:
#include <botan/botan.h>

这是我收到的错误信息:

    C:\Program Files\Microsoft Visual Studio 14.0\VC\INCLUDE\xmemory0(876): error C2664: 'Botan::secure_allocator<_Newfirst>::secure_allocator(const Botan::secure_allocator<_Newfirst> &)': cannot convert
argument 1 from 'std::_Wrap_alloc<Botan::secure_allocator<Botan::byte>>' to 'const Botan::secure_allocator<_Newfirst> &'
        with
        [
            _Newfirst=std::_Container_proxy
        ]
C:\Program Files\Microsoft Visual Studio 14.0\VC\INCLUDE\xmemory0(876): note: Reason: cannot convert from 'std::_Wrap_alloc<Botan::secure_allocator<Botan::byte>>' to 'const Botan::secure_allocator<_Ne
wfirst>'
        with
        [
            _Newfirst=std::_Container_proxy
        ]
C:\Program Files\Microsoft Visual Studio 14.0\VC\INCLUDE\xmemory0(876): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
C:\Program Files\Microsoft Visual Studio 14.0\VC\INCLUDE\vector(587): note: see reference to function template instantiation 'std::_Wrap_alloc<Botan::secure_allocator<_Newfirst>>::_Wrap_alloc<std::_Wr
ap_alloc<Botan::secure_allocator<Botan::byte>>>(_Other &) noexcept' being compiled
        with
        [
            _Newfirst=std::_Container_proxy,
            _Other=std::_Wrap_alloc<Botan::secure_allocator<Botan::byte>>
        ]
C:\Program Files\Microsoft Visual Studio 14.0\VC\INCLUDE\vector(587): note: see reference to function template instantiation 'std::_Wrap_alloc<Botan::secure_allocator<_Newfirst>>::_Wrap_alloc<std::_Wr
ap_alloc<Botan::secure_allocator<Botan::byte>>>(_Other &) noexcept' being compiled
        with
        [
            _Newfirst=std::_Container_proxy,
            _Other=std::_Wrap_alloc<Botan::secure_allocator<Botan::byte>>
        ]
C:\Program Files\Microsoft Visual Studio 14.0\VC\INCLUDE\vector(585): note: while compiling class template member function 'void std::_Vector_alloc<std::_Vec_base_types<_Ty,_Alloc>>::_Free_proxy(void)
'
        with
        [
            _Ty=Botan::byte,
            _Alloc=Botan::secure_allocator<Botan::byte>
        ]
C:\Program Files\Microsoft Visual Studio 14.0\VC\INCLUDE\vector(552): note: see reference to function template instantiation 'void std::_Vector_alloc<std::_Vec_base_types<_Ty,_Alloc>>::_Free_proxy(voi
d)' being compiled
        with
        [
            _Ty=Botan::byte,
            _Alloc=Botan::secure_allocator<Botan::byte>
        ]
C:\Program Files\Microsoft Visual Studio 14.0\VC\INCLUDE\vector(679): note: see reference to class template instantiation 'std::_Vector_alloc<std::_Vec_base_types<_Ty,_Alloc>>' being compiled
        with
        [
            _Ty=Botan::byte,
            _Alloc=Botan::secure_allocator<Botan::byte>
        ]
c:\Botan\include\botan-1.11\botan/rng.h(43): note: see reference to class template instantiation 'std::vector<Botan::byte,Botan::secure_allocator<Botan::byte>>' being compiled
NMAKE : fatal error U1077: 'C:\PROGRA~1\MICROS~3.0\VC\bin\cl.exe' : return code '0x2'
Stop.
NMAKE : fatal error U1077: '"C:\Program Files\Microsoft Visual Studio 14.0\VC\BIN\nmake.exe"' : return code '0x2'
Stop.
NMAKE : fatal error U1077: '"C:\Program Files\Microsoft Visual Studio 14.0\VC\BIN\nmake.exe"' : return code '0x2'
Stop.

自从我能够编译和运行Botan测试以来,我有一种错过了点什么的感觉,但我不知道是什么。有人有这方面的经验吗? (顺便说一句:同样的代码可以很好地编译g++ 4.9)


std::_Wrap_alloc <Botan::secure_allocator <Botan::byte>>' 转换为 'const Botan::secure_allocator <_Newfirst> &':也许传递的 std::_Wrap_alloc对象需要一些类似于operator *的间接操作,以获取一个可能可转换为Botan::secure_allocator<_Newfirst>Botan::secure_allocatorBotan::byte` 对象? - Aleksey F.
1
可能是缺少了一个头文件(以允许转换Botan::secure_allocator)? - Jarod42
我已经在答案中添加了另一个可能的解决方法。 - bogdan
Botan从未与VS 2015进行过测试,因此库中可能存在问题。感谢您提出这个问题。 - Simon Warta
Botan 1.11.20昨天发布,修复了该问题。再次感谢@bogdan! - Simon Warta
1个回答

6
看起来 来源 表明 Botan::secure_allocator 没有提供以下形式的模板构造函数。
template<class U> secure_allocator(const secure_allocator<U>& other);

这是标准要求。在当前工作草案N4527中,相关部分在[17.6.3.5]表28 - 分配器要求中;第9段的示例也很有用。
因此,我们不能因为VC 14附带的标准库实现需要编译而责怪它。在我看来,错误出在Botan这边。
一个快速的解决方法是将这样的定义添加到Botan::secure_allocator:
template<class U> secure_allocator(const secure_allocator<U>&) BOTAN_NOEXCEPT { }

由于此分配器模板的实例没有任何非静态数据成员,因此空的主体应该是可以的。但是,我不熟悉库,而且我们在谈论密码学,因此,在使用此功能进行任何重要操作之前,请与库作者确认更改。


另一个可能的解决方法:
我注意到调用混合类型构造函数的代码似乎只在启用迭代器调试时才启用,这在调试模式下默认发生。
你尝试过以发布模式编译吗?如果我的观察是正确的,您将不再收到此错误,因为迭代器调试的附加机制将被禁用。
要在调试模式下获得相同的行为,请将_ITERATOR_DEBUG_LEVEL宏全局设置为0
调试迭代器可以用于检测错误(只要性能损失不影响您),因此我不会将其用作永久修复,但如果您不想修改Botan标头文件,则可以将其用作临时解决方法。
这也可以解释为什么您能够编译测试:也许它们是在发布模式下编译的,或者以某种组合的设置禁用了迭代器调试?

我理解你的意思是建议添加一个显式的复制构造函数?这可以解释错误,因为其他编译器会隐式地执行此操作。 - Simon Warta
@SimonWarta 那不是一个拷贝构造函数。拷贝构造函数不能是模板特化,并且它们的第一个参数需要是正在构造的类型的左值引用(我描述的可以接受secure_allocator模板的任何其他特化)。据我所知,VC 14在隐式生成特殊成员函数方面做得很好,所以那不是问题。不同的行为似乎是由于VC14 STL中的迭代器调试引起的,但那仍然不符合分配器的标准 - 需要该模板构造函数。 - bogdan
请问您能否将您的更改及相关背景信息作为一个 pull request 添加到 Botan 中呢?这样我们可以从其他开发者那里获得反馈。当涉及到模板时,我并不是专家。 - Simon Warta
那个 pull request 已经合并了吗?还是在某个地方在线上,我可以尝试一下?我现在正面临着完全相同的问题。 - j00hi
2
根据Simon Warta的上面的评论,版本1.11.20包含了修复。如果您需要使用旧版本并希望手动应用更改,则差异在此处 - bogdan
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接