Ошибка компиляции ботана VS2015
У меня странная ситуация здесь. Я пытаюсь использовать криптографическую библиотеку Botan с VS2015 (потому что некоторые другие части проекта используют тяжелый код C++11, который VS2013 не может скомпилировать), и я получаю довольно длинную ошибку компиляции (см. Ниже).
Попробовав разные вещи, я пришел к выводу, что даже если один из заголовков ботана включен в скомпилированный исходный файл C++, компилятор выдаст ошибку ниже. Прямо сейчас у меня есть одна строка в файле:
#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.
Так как я смог скомпилировать и запустить ботанические тесты, у меня такое чувство, что я что-то пропустил, но понятия не имею, что. У кого-нибудь есть опыт с этим? (Кстати: тот же код прекрасно компилируется с g++ 4.9)
1 ответ
Глядя на источники, кажется, что Botan::secure_allocator
не предоставляет конструктор шаблона формы
template<class U> secure_allocator(const secure_allocator<U>& other);
Это требуется стандартом. В текущем рабочем проекте N4527 соответствующие биты находятся в [17.6.3.5] Таблица 28 - Требования к распределителю; Также полезным является пример в пункте 9.
Таким образом, мы не можем винить стандартную реализацию библиотеки, которая поставляется с VC 14, за то, что она требуется для компиляции. Ошибка, на мой взгляд, на стороне Ботана.
Быстрое решение состоит в том, чтобы добавить такое определение Botan::secure_allocator
:
template<class U> secure_allocator(const secure_allocator<U>&) BOTAN_NOEXCEPT { }
Поскольку экземпляры этого шаблона распределителя не имеют нестатических элементов данных, пустое тело должно быть в порядке. Однако я не знаком с библиотекой, и мы здесь говорим о криптографии, поэтому, прежде чем использовать это для каких-либо серьезных вещей, пожалуйста, подтвердите изменение с авторами библиотеки.
Другой возможный обходной путь:
Я заметил, что код, который вызывает конструктор смешанного типа, кажется, включается только тогда, когда включена отладка итератора, что происходит по умолчанию в режиме отладки.
Вы пробовали компилировать в режиме релиза? Если мои наблюдения верны, вы больше не получите эту ошибку, так как дополнительный механизм отладки итератора будет отключен.
Чтобы получить такое же поведение в режиме отладки, установите _ITERATOR_DEBUG_LEVEL
макрос в 0
во всем мире.
Отладочные итераторы могут быть полезны для обнаружения ошибок (если это не влияет на производительность), поэтому я не буду использовать это как постоянное исправление, но это может быть полезно как временное решение, если вы не хотите изменить заголовочный файл Botan.
Это также может объяснить, почему вы смогли скомпилировать тесты: возможно, они скомпилированы в режиме выпуска или, в любом случае, с комбинацией настроек, которая отключает отладку итератора?