5

This simple code can't be compiled with the -std=c++20 option:

#include <limits>
#include <boost/multiprecision/float128.hpp>

namespace bm = boost::multiprecision;

int main()
{
  auto const m = std::numeric_limits<bm::float128>::max();
}

The compilation command and its error output:

hekto@ubuntu:~$ g++ -std=c++20 test.cpp
In file included from test.cpp:2:
/usr/include/boost/multiprecision/float128.hpp: In instantiation of ‘static std::numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::number_type std::numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max() [with boost::multiprecision::expression_template_option ExpressionTemplates = boost::multiprecision::et_off; std::numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::number_type = boost::multiprecision::number<boost::multiprecision::backends::float128_backend, boost::multiprecision::et_off>]’:
test.cpp:8:53:   required from here
/usr/include/boost/multiprecision/float128.hpp:728:55: error: could not convert ‘boost::multiprecision::quad_constants::quad_max’ from ‘const __float128’ to ‘std::numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, boost::multiprecision::et_off> >::number_type’ {aka ‘boost::multiprecision::number<boost::multiprecision::backends::float128_backend, boost::multiprecision::et_off>’}
  728 |    static number_type (max)() BOOST_NOEXCEPT { return BOOST_MP_QUAD_MAX; }
      |                                                       ^~~~~~~~~~~~~~~~~
      |                                                       |
      |                                                       const __float128

Why is that?

  • OS: Xubuntu 20.04.4 LTS
  • Compiler: g++ (Ubuntu 10.3.0-1ubuntu1~20.04) 10.3.0
  • Boost: 1.71.0
HEKTO
  • 3,876
  • 2
  • 24
  • 45
  • 3
    Is that the *only* message in the full and complete build log? What is the *exact* message? Please show us exactly how you build (full command with all options and flags), the full and complete build log output, and what version of Boost you have installed. – Some programmer dude Jul 24 '22 at 05:19
  • Replicates - live - https://godbolt.org/z/WhanYK8fe – Richard Critten Jul 24 '22 at 07:40

2 Answers2

3

Directly from the documentation:

When compiling with gcc, you need to use the flag --std=gnu++11/14/17, as the suffix Q is a GNU extension. Compilation fails with the flag --std=c++11/14/17 unless you also use -fext-numeric-literals.

The same applies for c++20/gnu++20, the docs merely haven't yet been updated for that revision.

ildjarn
  • 62,044
  • 9
  • 127
  • 211
3

The documentation states:

When compiling with gcc, you need to use the flag --std=gnu++11/14/17, as the suffix 'Q' is a GNU extension. Compilation fails with the flag --std=c++11/14/17 unless you also use -fext-numeric-literals.

So you need to specify --std=gnu++20 instead of --std=c++20. The boost documentation is not up-to-date. The flag enables various GNU extensions, one of it being __float128.

See example on godbolt.

The underlying reason for the compiler error is that without the --std=gnu++17 or --std=gnu++20 flag, _GLIBCXX_USE_FLOAT128 is not defined, meaning BOOST_HAS_FLOAT128 is not defined, meaning __float128 is not recognized as number_kind_floating_point (but as number_kind_unknown). This means that boost::multiprecision::number cannot be implicitly constructed from a __float128 because is_restricted_conversion<__float128, boost::multiprecision::float128_backend>::value is true because bm::detail::is_lossy_conversion<__float128, boost::multiprecision::float128_backend>::value is true, because __float128 is number_kind_unknown instead of number_kind_floating_point.

I.e. in short, without gnu++20, the boost::multiprecision::float128 type is not supported.

Sedenion
  • 5,421
  • 2
  • 14
  • 42
  • s/is broken/is not supported/, but fine explanation otherwise, +1 – sehe Jul 24 '22 at 13:36
  • The flag `-std=gnu++11/14/17/20` helped, but the flag`-fext-numeric-literals` did not, so it looks like the documentation needs some corrections... thank you! – HEKTO Jul 24 '22 at 16:08
  • 2
    Well, `-fext-numeric-literals` enables the Q suffix but does not define `_GLIBCXX_USE_FLOAT128`. Which then causes the described problems. So yes, the boost documentation is wrong to say that `-fext-numeric-literals` is sufficient. – Sedenion Jul 24 '22 at 16:10
  • The problem here looks even more deep - the GCC with option `-std=gnu++17` couldn't **link** my code with the `std::cout << std::numeric_limits::max()` statement. The `quadmath_snprintf` function wasn't found – HEKTO Jul 25 '22 at 04:08
  • 2
    Once again from the [boost documentation](https://www.boost.org/doc/libs/1_79_0/libs/multiprecision/doc/html/boost_multiprecision/tut/floats/float128.html): `You will need to link to libquadmath.dll with the link command -lquadmath and ensure that the DLL is visible by the linker. If you are using the B2/bjam build system then commands-lQUADMATH and -L"path/to/lib" will be needed.` – Sedenion Jul 25 '22 at 05:36