Ale*_*xei 7 c++ gcc boost clang bigint
我有以下应该转换std::array<uint8_t>为BigIntie 的代码示例boost::multiprecision::cpp_int。我使用 MSYS2 中的 clang64 15.0.7 (\xd0\xa1++17) 编译此代码。代码工作正常并将 uint8_t 数组转换为 BigInt。
#include <string>\n#include <iostream>\n#include <boost/multiprecision/cpp_int.hpp>\n\nusing BigInt = boost::multiprecision::cpp_int;\n\nconst auto b = std::array<uint8_t, 16>{\n 0x11, 0x22, 0x33, 0x44,\n 0x11, 0x22, 0x33, 0x44,\n 0x11, 0x22, 0x33, 0x44,\n 0x11, 0x22, 0x33, 0x44\n};\n\nint main() {\n size_t shift = 0;\n auto initial = BigInt{};\n\n auto i = std::accumulate(\n b.cbegin(),\n b.cend(),\n initial,\n [&shift](const BigInt &acc, uint8_t it) {\n auto byte = BigInt{it};\n auto result = acc | (byte << shift);\n shift += CHAR_BIT;\n return result;\n }\n );\n\n std::cout << "Boost integer " << i << std::endl;\n}\nRun Code Online (Sandbox Code Playgroud)\n但是当我将 ASAN 选项添加到我的 CMakeFile 时:
\nadd_compile_options(-fsanitize=address -fsanitize=undefined)\nadd_link_options(-fsanitize=address -fsanitize=undefined)\nRun Code Online (Sandbox Code Playgroud)\n代码崩溃并显示以下日志。我还发现boost cpp_int stack unwind 崩溃,但此问题仅适用于 GCC 7.1/8.1,并且未针对 clang 得到确认。除了在 ASAN 下的“简单”“boost”表达式cpp_int(对于 GCC 7.3.3)上发生类似的崩溃之外,例如m_state = (data ^ key) & mask;所有项目都是cpp_int。我做错了什么吗cpp_int?
==8032==ERROR: AddressSanitizer: stack-buffer-underflow on address 0x00f79ccfed58 at pc 0x7ff60fb5fb02 bp 0x00f79ccfe200 sp 0x00f79ccfe248\nREAD of size 8 at 0x00f79ccfed58 thread T0\n #0 0x7ff60fb5fb01 in void boost::multiprecision::backends::left_shift_byte<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>>(boost::multiprecision::backe\nnds::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>&, unsigned __int128) C:/msys64/clang64/include/boost/multiprecision/cpp_int/bitwise.hpp:334:25\n #1 0x7ff60fb5f314 in std::__1::enable_if<!is_trivial_cpp_int<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>>::value, void>::type boost::multiprecision:\n:backends::eval_left_shift<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>(boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::c\npp_int_check_type)0, std::__1::allocator<unsigned long long>>&, unsigned __int128) C:/msys64/clang64/include/boost/multiprecision/cpp_int/bitwise.hpp:500:7\n #2 0x7ff60fb5f002 in void boost::multiprecision::default_ops::eval_left_shift<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, boost::multiprecision::ba\nckends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, unsigned long long>(boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost:\n:multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>&, boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>> const&, unsigned long long\n) C:/msys64/clang64/include/boost/multiprecision/detail/default_ops.hpp:890:4\n #3 0x7ff60fb5ed30 in void boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_opt\nion)1>::do_assign_left_shift<boost::multiprecision::detail::expression<boost::multiprecision::detail::terminal, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__\n1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, void, void, void>, unsigned long long>(boost::multiprecision::detail::expression<boost::multiprecision::detail::terminal, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ul\nl, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, void, void, void> const&, unsigned long long const&, boost::multiprecision::detail::terminal const&) C:/msys64\n/clang64/include/boost/multiprecision/number.hpp:1665:7\n #4 0x7ff60fb5964a in void boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_opt\nion)1>::do_assign<boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::alloca\ntor<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void>>(boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::mu\nltiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void> const&, boost::multiprecision::detail::shift_left const&) C:/msys64/clang64/include/boost/m\nultiprecision/number.hpp:1616:7\n #5 0x7ff60fb5a979 in void boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_opt\nion)1>::do_assign<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multipre\ncision::expression_template_option)1>, unsigned long long, void, void>(boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::m\nultiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void> const&, std::__1::integral_constant<bool, true> const&) C:/msys64/clang64/include/boost/multiprecision/number.hpp:1222:7\n #6 0x7ff60fb5a719 in std::__1::enable_if<std::is_convertible<boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multipr\necision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void>::result_type, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer\n_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>>::value, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boos\nt::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>&>::type boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecisi\non::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>::operator=<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integ\ner_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void>(boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number\n<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void> const&) C:/msys64/c\nlang64/include/boost/multiprecision/number.hpp:319:7\n #7 0x7ff60fb5a2db in boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1\n>::number<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::\nexpression_template_option)1>, unsigned long long, void, void>(boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprec\nision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void> const&, std::__1::enable_if<std::is_convertible<boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::mu\nltiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void>\n::result_type, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>>::value,\n void>::type*) C:/msys64/clang64/include/boost/multiprecision/number.hpp:440:13\n #8 0x7ff60fb58d7d in void boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_opt\nion)1>::do_bitwise_or<boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::al\nlocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void>, boost::multiprecision::detail::shift_left>(boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::b\nackends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void> const&, boost::multiprecision::detail::shift\n_left const&) C:/msys64/clang64/include/boost/multiprecision/number.hpp:2116:17\n #9 0x7ff60fb57f63 in void boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_opt\nion)1>::do_assign<boost::multiprecision::detail::expression<boost::multiprecision::detail::bitwise_or, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::alloca\ntor<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1,\n (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void>, void, void>>(boost::multiprecision::detail::expression<boost::multiprecision::detail::bitwise_or, boost::multiprecision::nu\nmber<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::detail::expression<boost\n::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_temp\nlate_option)1>, unsigned long long, void, void>, void, void> const&, boost::multiprecision::detail::bitwise_or const&) C:/msys64/clang64/include/boost/multiprecision/number.hpp:1521:10\n #10 0x7ff60fb579b9 in void boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_op\ntion)1>::do_assign<boost::multiprecision::detail::bitwise_or, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multipr\necision::expression_template_option)1>, boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_ty\npe)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void>, void, void>(boost::multiprecision::detail::expression<boost::multiprecision::detail::bitwise_or, boost::multiprecision::number<boost::multiprecision::backends::cpp_\nint_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boos\nt::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, \nvoid>, void, void> const&, std::__1::integral_constant<bool, true> const&) C:/msys64/clang64/include/boost/multiprecision/number.hpp:1222:7\n #11 0x7ff60fb56cf9 in std::__1::enable_if<std::is_convertible<boost::multiprecision::detail::expression<boost::multiprecision::detail::bitwise_or, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multip\nrecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0\null, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void>, void, void>::result_type, boost::multiprecision::number<boost::multiprecisi\non::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>>::value, boost::multiprecision::number<boost::multiprecision::backends::\ncpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>&>::type boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend\n<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>::operator=<boost::multipr
seh*_*ehe 10
表达式模板再次出击!
您的 lambda 表达式的结果不是BigInt. 这是一个惰性引用操作数的表达式(非常简化):
detail::expression<detail::bitwise_or, number<backends::cpp_int_backend<...>, et_on>,
detail::expression<detail::shift_left, number<backends::cpp_int_backend<...>, et_on>,
unsigned long, void, void>,
void, void>;
Run Code Online (Sandbox Code Playgroud)
修复即可消除问题:
BigInt result = acc | (byte << shift); // look, no auto!
Run Code Online (Sandbox Code Playgroud)
或者
std::accumulate(b.cbegin(), b.cend(), initial,
[&shift](BigInt const& acc, uint8_t it)
-> BigInt { // trailing return
Run Code Online (Sandbox Code Playgroud)
更通用的解决方案是完全禁用表达式模板BigInt:
//using BigInt = boost::multiprecision::cpp_int;
using BigInt =
boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>, boost::multiprecision::et_off>;
Run Code Online (Sandbox Code Playgroud)