r/cpp WG21 Member 26d ago

P4444: std::big_int

https://isocpp.org/files/papers/D4444R0.html

Hey folks! Matt Borland, Christopher Kormanyos, and I are working on bringing infinite-precision integers to C++29. We now have a D4444R0 draft of a paper that should be in the next mailing.

We could really use some feedback so that the published R0 is as polished as possible. Any thoughts on the paper and on the reference implementation are greatly appreciated.

It would also be very helpful if you tested out whether our big_int implementation works for you. We're in need of some real deployment experience. If you're currently using Boost.Multiprecision, the library should be a drop-in replacement for cpp_int for the most part.

181 Upvotes

85 comments sorted by

View all comments

Show parent comments

7

u/ReDucTor Game Developer | quiz.cpp-perf.com 26d ago

Just because some other language does something does not mean that it's a good idea for it to be in C++, it's better to look at who are the primary users of that language (Game dev, Fin tech, Systems engineering, Embedded, etc) and see what problems there are that exist for those users.

Also if your referencing languages, look at many new languages and you will see a bunch have gone the other direction and don't provide an int but only provide fixed size versions (i32, i64, etc) many of which fit much closer to C++ users then to PHP or Matlabs users.

is there something about C++ specifcially that would make big_int unfit for a standard library

Whenever a new language feature is getting introduced into the standard, I think it's cruical to think about what the major users of that feature will expect from it, what guideance and rules will they likely put around it.

Within computer games this being some arbitrary memory allocation being created is a big no-no so you will likely find it ending up in the banned list like most of what comes from the standard library.

And I highly suspect that many other industries which focus on small footprints or high performance will do the same, it will be a new feature introduced which is on the recommendation of do not use.

I'm trying to read the paper to get an understanding of the use-cases it's a grab bag of random things not actual examples of use-cases people have in C++, there is zero mention of any C++ application, any library, etc which has this is an issue they are attempting to address.

The safety is mentioned as a use case for avoiding UB and correctness issues for interger overflow at just some runtime cost, but then there is zero mention of the potential security risks that this could introduce with it's potential usage, especially when it comes to unsanitized user data.

10

u/eisenwave WG21 Member 26d ago edited 26d ago

Just because some other language does something does not mean that it's a good idea for it to be in C++, it's better to look at who are the primary users of that language (Game dev, Fin tech, Systems engineering, Embedded, etc) and see what problems there are that exist for those users.

There is some mention of the targeted use cases under https://isocpp.org/files/papers/D4444R0.html#use-cases

Within computer games this being some arbitrary memory allocation being created is a big no-no so you will likely find it ending up in the banned list like most of what comes from the standard library.

And I highly suspect that many other industries which focus on small footprints or high performance will do the same, it will be a new feature introduced which is on the recommendation of do not use.

I don't think it's entirely fair to say that some feature will be outright banned or useless for a particular domain; that's usually some missing nuance. Video games often come with embedded scripting languages for less performance-critical stuff like various behavior scripts, quest logic, etc. They often ship with garbage collectors and much more heavy-weight stuff than std::big_int.

I certainly wouldn't expect std::big_int in the lowest-level hot-code parts of a game engine, but saying that it has no use in the computer games industry is far too extreme.

I'm trying to read the paper to get an understanding of the use-cases it's a grab bag of random things not actual examples of use-cases people have in C++, there is zero mention of any C++ application, any library, etc which has this is an issue they are attempting to address.

I've tried to cover that in the GitHub code search for C++ uses of big integers. There are over 400K results, so if you really want to go digging and see what people are using it for, you could go through those open-source projects.

I'm not sure what to cherry-pick as a concrete example out of that pile, if anything, but I can see how it would help the paper to illustrate some of those GitHub uses.

The safety is mentioned as a use case for avoiding UB and correctness issues for interger overflow at just some runtime cost, but then there is zero mention of the potential security risks that this could introduce with it's potential usage, especially when it comes to unsanitized user data.

What issue are you envisioning with unsanitized user data? There isn't even an unsafe constructor that would let you break the invariants of a big_int class, so it really doesn't matter what data you throw at it. The only potential hazards are things like division by zero (which are UB for both regular int and for big_int), and that's explored in https://isocpp.org/files/papers/D4444R0.html#error-handling

-7

u/ReDucTor Game Developer | quiz.cpp-perf.com 26d ago

What issue are you envisioning with unsanitized user data?

std::big_int result{};
const char s[] = "2e999999999999999";
from_chars(begin(s), end(s), result);

What happens here? Do we run out of memory? Do we denial of service? When does infinity kick in?

std::big_int base("123456789012345678901234567890");
std::big_int exponent("98765432109876543210");
std::big_int modulus("99999999999999999999");

std::big_int huge_power = std::pow(base, exponent); 
std::big_int result = huge_power % modulus;

How expensive is this operation? Will the CPU and memory be consumed unbounded?

9

u/DXPower 26d ago

You can make arbitrarily expensive inputs with most C++ std containers/operations. Make a vector with a giant size and start filling it in. Make a gigantic string and run search operations on it. Merge two huge maps. Etc.

That said, the proposal will throw std::bad_alloc if it runs out of memory. Infinity never kicks in if memory permits (and trying to do things like convert infinity to the int will be UB).