Comments (14)
I wonder if this is a problem in qtum or in boost itself - looks like the boost's numerics.ipp
is not self sufficient - uses pow()
but does not include the header that provides it.
from cpp-eth-qtum.
Would this patch to cpp-ethereum workaround the problem?
--- utils/json_spirit/json_spirit_reader_template.h.orig 2018-07-11 19:12:36.155318000 +0200
+++ utils/json_spirit/json_spirit_reader_template.h 2018-07-11 19:11:26.015016000 +0200
@@ -16,6 +16,7 @@
#include <boost/version.hpp>
#if BOOST_VERSION >= 103800
+ #include <boost/rational.hpp>
#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_confix.hpp>
#include <boost/spirit/include/classic_escape_char.hpp>
from cpp-eth-qtum.
No. pow()
is ambiguous because that header is already included.
In file included from cpp-ethereum/libethereum/ChainParams.cpp:22:
In file included from cpp-ethereum/libethereum/ChainParams.h:24:
In file included from ./cpp-ethereum/libdevcore/Common.h:51:
In file included from /usr/local/include/boost/multiprecision/cpp_int.hpp:18:
In file included from /usr/local/include/boost/multiprecision/rational_adaptor.hpp:19:
/usr/local/include/boost/rational.hpp:1:2: error: bootlegging test
from cpp-eth-qtum.
@jeking3, any clue why pow()
from Boost.Rational would overshadow std::pow
as used by Boost.Spirit?
from cpp-eth-qtum.
pow was added to rational in 1.68 based on an older PR that had been outstanding:
In particular it is a template which probably changes the resolution order, and I think it's in the boost namespace so any other boost library will resolve to it if the headers are included. I added a comment to the merged PR and will get some experts to comment.
from cpp-eth-qtum.
There's a potential fix for this here - if you could apply the public header change to your copy and see if it resolves the issue that would be great.
I was not able to come up with a unit test that exposed the original issue.
I'd like to get this fix into the upcoming 1.68.0 official release.
Thanks.
from cpp-eth-qtum.
@jeking3, boostorg/rational@2a92177e83b5 doesn't help, see error log
--- error.log Boost 1.68.0 Beta 1
+++ error.log Boost 1.68.0 Beta 1 + boostorg/rational@2a92177e83b5
@@ -1,56 +1,56 @@
In file included from cpp-ethereum/libethereum/ChainParams.cpp:23:
In file included from ./cpp-ethereum/utils/json_spirit/JsonSpiritHeaders.h:28:
In file included from ./cpp-ethereum/utils/json_spirit/../json_spirit/json_spirit_reader_template.h:19:
In file included from /usr/local/include/boost/spirit/include/classic_core.hpp:11:
In file included from /usr/local/include/boost/spirit/home/classic/core.hpp:33:
In file included from /usr/local/include/boost/spirit/home/classic/core/primitives/numerics.hpp:18:
/usr/local/include/boost/spirit/home/classic/core/primitives/impl/numerics.ipp:407:31: error: no matching function for call to 'pow'
* pow(T(10), T(-hit.length())));
^~~
/usr/local/include/boost/spirit/home/classic/core/composite/impl/directives.ipp:98:24: note: in instantiation of function template specialization 'boost::spirit::classic::impl::real_parser_impl<boost::spirit::classic::match<double>, double, boost::spirit::classic::strict_real_parser_policies<double> >::parse_main<boost::spirit::classic::scanner<std::__1::__wrap_iter<const char *>, boost::spirit::classic::scanner_policies<boost::spirit::classic::no_skipper_iteration_policy<boost::spirit::classic::skipper_iteration_policy<boost::spirit::classic::iteration_policy> >, boost::spirit::classic::match_policy, boost::spirit::classic::action_policy> > >' requested here
RT hit = p.parse_main(scan.change_policies(policies_t(scan)));
^
/usr/local/include/boost/spirit/home/classic/core/primitives/impl/numerics.ipp:463:30: note: in instantiation of function template specialization 'boost::spirit::classic::impl::implicit_lexeme_parse<boost::spirit::classic::match<double>, boost::spirit::classic::impl::real_parser_impl<boost::spirit::classic::match<double>, double, boost::spirit::classic::strict_real_parser_policies<double> >, boost::spirit::classic::scanner<std::__1::__wrap_iter<const char *>, boost::spirit::classic::scanner_policies<boost::spirit::classic::skipper_iteration_policy<boost::spirit::classic::iteration_policy>, boost::spirit::classic::match_policy, boost::spirit::classic::action_policy> >, boost::spirit::classic::iteration_policy>' requested here
return impl::implicit_lexeme_parse<RT>(this_, scan, scan);
^
/usr/local/include/boost/spirit/home/classic/core/primitives/numerics.hpp:245:72: note: in instantiation of function template specialization 'boost::spirit::classic::impl::real_parser_impl<boost::spirit::classic::match<double>, double, boost::spirit::classic::strict_real_parser_policies<double> >::parse<boost::spirit::classic::scanner<std::__1::__wrap_iter<const char *>, boost::spirit::classic::scanner_policies<boost::spirit::classic::skipper_iteration_policy<boost::spirit::classic::iteration_policy>, boost::spirit::classic::match_policy, boost::spirit::classic::action_policy> > >' requested here
return impl::real_parser_impl<result_t, T, RealPoliciesT>::parse(scan);
^
/usr/local/include/boost/spirit/home/classic/core/composite/actions.hpp:113:44: note: in instantiation of function template specialization 'boost::spirit::classic::real_parser<double, boost::spirit::classic::strict_real_parser_policies<double> >::parse<boost::spirit::classic::scanner<std::__1::__wrap_iter<const char *>, boost::spirit::classic::scanner_policies<boost::spirit::classic::skipper_iteration_policy<boost::spirit::classic::iteration_policy>, boost::spirit::classic::match_policy, boost::spirit::classic::action_policy> > >' requested here
result_t hit = this->subject().parse(scan);
^
/usr/local/include/boost/spirit/home/classic/core/composite/alternative.hpp:67:49: note: in instantiation of function template specialization 'boost::spirit::classic::action<boost::spirit::classic::real_parser<double, boost::spirit::classic::strict_real_parser_policies<double> >, boost::function<void (double)> >::parse<boost::spirit::classic::scanner<std::__1::__wrap_iter<const char *>, boost::spirit::classic::scanner_policies<boost::spirit::classic::skipper_iteration_policy<boost::spirit::classic::iteration_policy>, boost::spirit::classic::match_policy, boost::spirit::classic::action_policy> > >' requested here
if (result_t hit = this->left().parse(scan))
^
/usr/local/include/boost/spirit/home/classic/core/composite/alternative.hpp:67:49: note: (skipping 11 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
/usr/local/include/boost/spirit/home/classic/core/scanner/impl/skipper.ipp:155:13: note: in instantiation of function template specialization 'boost::spirit::classic::impl::phrase_parser<boost::spirit::classic::space_parser>::parse<std::__1::__wrap_iter<const char *>, json_spirit::Json_grammer<json_spirit::Value_impl<json_spirit::Config_map<std::__1::basic_string<char> > >, std::__1::__wrap_iter<const char *> > >' requested here
parse(first, last, p.derived(), skip.derived());
^
./cpp-ethereum/utils/json_spirit/../json_spirit/json_spirit_reader_template.h:523:47: note: in instantiation of function template specialization 'boost::spirit::classic::parse<std::__1::__wrap_iter<const char *>, json_spirit::Json_grammer<json_spirit::Value_impl<json_spirit::Config_map<std::__1::basic_string<char> > >, std::__1::__wrap_iter<const char *> >, boost::spirit::classic::space_parser>' requested here
spirit_namespace::parse( begin, end,
^
./cpp-ethereum/utils/json_spirit/../json_spirit/json_spirit_reader_template.h:552:21: note: in instantiation of function template specialization 'json_spirit::read_range_or_throw<std::__1::__wrap_iter<const char *>, json_spirit::Value_impl<json_spirit::Config_map<std::__1::basic_string<char> > > >' requested here
begin = read_range_or_throw( begin, end, value );
^
./cpp-ethereum/utils/json_spirit/../json_spirit/json_spirit_reader_template.h:573:16: note: in instantiation of function template specialization 'json_spirit::read_range<std::__1::__wrap_iter<const char *>, json_spirit::Value_impl<json_spirit::Config_map<std::__1::basic_string<char> > > >' requested here
return read_range( begin, s.end(), value );
^
cpp-ethereum/libethereum/ChainParams.cpp:58:15: note: in instantiation of function template specialization 'json_spirit::read_string<std::__1::basic_string<char>, json_spirit::Value_impl<json_spirit::Config_map<std::__1::basic_string<char> > > >' requested here
json_spirit::read_string(_json, val);
^
-/usr/local/include/boost/rational.hpp:873:26: note: candidate template ignored: could not match 'rational<type-parameter-0-0>' against 'double'
-inline rational<IntType> pow(rational<IntType> base, IntType exponent)
- ^
+/usr/local/include/boost/rational.hpp:875:1: note: candidate template ignored: could not match 'rational<type-parameter-0-0>' against 'double'
+pow(rational<IntType> base, ExpType exponent)
+^
In file included from cpp-ethereum/libethereum/ChainParams.cpp:23:
In file included from ./cpp-ethereum/utils/json_spirit/JsonSpiritHeaders.h:28:
In file included from ./cpp-ethereum/utils/json_spirit/../json_spirit/json_spirit_reader_template.h:19:
In file included from /usr/local/include/boost/spirit/include/classic_core.hpp:11:
In file included from /usr/local/include/boost/spirit/home/classic/core.hpp:33:
In file included from /usr/local/include/boost/spirit/home/classic/core/primitives/numerics.hpp:18:
/usr/local/include/boost/spirit/home/classic/core/primitives/impl/numerics.ipp:446:30: error: no matching function for call to 'pow'
n *= pow(T(10), T(e_n_hit.value()));
^~~
-/usr/local/include/boost/rational.hpp:873:26: note: candidate template ignored: could not match 'rational<type-parameter-0-0>' against 'double'
-inline rational<IntType> pow(rational<IntType> base, IntType exponent)
- ^
+/usr/local/include/boost/rational.hpp:875:1: note: candidate template ignored: could not match 'rational<type-parameter-0-0>' against 'double'
+pow(rational<IntType> base, ExpType exponent)
+^
2 errors generated.
from cpp-eth-qtum.
The error message diff is useful; it means the previous template was working okay.
Okay, so now I'm wondering if "cmath" hasn't been included where it is needed for pow(), or if perhaps you also changed your language level, since C++11 omits some of the pow() functions from C++03?
from cpp-eth-qtum.
It looks like this file includes "cmath", and the error log shows that the type T is a double:
/usr/local/include/boost/spirit/home/classic/core/composite/impl/directives.ipp:98:24: note: in instantiation of function template specialization 'boost::spirit::classic::impl::real_parser_impl<boost::spirit::classic::match<double>, double, boost::spirit::classic::strict_real_parser_policies<double> >::parse_main<boost::spirit::classic::scanner<std::__1::__wrap_iter<const char *>, boost::spirit::classic::scanner_policies<boost::spirit::classic::no_skipper_iteration_policy<boost::spirit::classic::skipper_iteration_policy<boost::spirit::classic::iteration_policy> >, boost::spirit::classic::match_policy, boost::spirit::classic::action_policy> > >' requested here
RT hit = p.parse_main(scan.change_policies(policies_t(scan)));
The line of code in question casts both values to T, which is double:
/usr/local/include/boost/spirit/home/classic/core/primitives/impl/numerics.ipp:446:30: error: no matching function for call to 'pow'
n *= pow(T(10), T(e_n_hit.value()));
The documentation shows the second invocation recipe for std::pow should match:
https://en.cppreference.com/w/cpp/numeric/math/pow
Unless there's another pow defined somewhere, but ultimately the one in "cmath" should match for T type "double".
Out of curiosity, what happens if you simply remove the pow() template from the rational header? I wonder if this is due to changes in Boost.Spirit and it just looks like a Boost.Rational issue, but is not?
from cpp-eth-qtum.
qtum is built with -std=c++11
, boost is built with -std=gnu++14
(default since Clang 6 and GCC 6). pow()
ambiguity disappears if the following call is commented out.
cpp-eth-qtum/utils/json_spirit/json_spirit_reader_template.h
Lines 523 to 525 in 8db7fc1
from cpp-eth-qtum.
Our of curiosity, what happens if you simply remove the pow() template from the rational header?
ChainParams.cpp (the affected file) builds fine.
from cpp-eth-qtum.
Root cause was identified in the rational PR. We're working on a fix.
from cpp-eth-qtum.
We're reverting the addition of pow() in Boost.Rational for 1.68.0.
from cpp-eth-qtum.
Thanks. qtum builds fine after applying boostorg/rational@3b31630778a4 on top of Beta 1.68.0 Beta1.
from cpp-eth-qtum.
Related Issues (5)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cpp-eth-qtum.