24

Is there some c++ proposal for Integer literal for fixed width integer types like this?

// i's type is unsigned int
auto i = 10u;
// j's type is uint32_t
auto j = 10u32;
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
康桓瑋
  • 33,481
  • 5
  • 40
  • 90
  • 1
    Related: https://stackoverflow.com/questions/36406333/fixed-width-integer-literals-in-c – Lukas-T Dec 03 '20 at 06:12
  • 1
    The old C99 way is to use macros in [stdint.h](https://en.cppreference.com/w/c/types/integer) - for example: `INT8_C(127)`, `UINT16_C(65535)`, `UINT32_C(10)`. – Nayuki Dec 03 '20 at 15:02

1 Answers1

29

Yes: P1280R0 Integer Width Literals (published 2018-10-05).

It proposes the following literals:

namespace std::inline literals::inline integer_literals {
  constexpr uint64_t operator ""u64 (unsigned long long arg);
  constexpr uint32_t operator ""u32 (unsigned long long arg);
  constexpr uint16_t operator ""u16 (unsigned long long arg);
  constexpr uint8_t operator ""u8 (unsigned long long arg);

  constexpr int64_t operator ""i64 (unsigned long long arg);
  constexpr int32_t operator ""i32 (unsigned long long arg);
  constexpr int16_t operator ""i16 (unsigned long long arg);
  constexpr int8_t operator ""i8 (unsigned long long arg);
}

And its update P1280R1 that "Modifies return types to actually be [u]int_leastXX_t and friends. This is to make sure that we are actually replacing the [U]INTxx_C macros, as these return a [u]int_leastXX_t":

namespace std::inline literals::inline integer_literals {
  constexpr uint_least64_t operator ""u64 (unsigned long long arg);
  constexpr uint_least32_t operator ""u32 (unsigned long long arg);
  constexpr uint_least16_t operator ""u16 (unsigned long long arg);
  constexpr uint_least8_t operator ""u8 (unsigned long long arg);

  constexpr int_least64_t operator ""i64 (unsigned long long arg);
  constexpr int_least32_t operator ""i32 (unsigned long long arg);
  constexpr int_least16_t operator ""i16 (unsigned long long arg);
  constexpr int_least8_t operator ""i8 (unsigned long long arg);
}

There is a 2019-06-12 update P1280R2 that makes the literals consteval instead of constexpr.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
bolov
  • 72,283
  • 15
  • 145
  • 224
  • 1
    fwiw, I think that update made it worse. If I write `auto x = 5u32`; I want a 32bit integer and not "maybe something else that will fail on other platform" – RiaD Dec 03 '20 at 15:08
  • 3
    @RiaD -- it's `uint32_t` that will fail on some other platform. `uint_least32_t` is **always** available; `uint32_t` won't exist on (admittedly unusual) platforms that don't have a native 32-bit integer type. That's an inherent ambiguity with fixed-size integer types: you might want an exact size, or you might want something large enough to hold some number of bits. – Pete Becker Dec 03 '20 at 15:59
  • 4
    @PeteBecker 1) "platform doesn't support uint32, so I won't compile 5u32" is straightforward compiler error 2) "in some random place where uint_least32_t is used, some overloading is now ambiguous" (suppose that uint32_least_t=unsigned long long and the same example will be broken as in P1280) is less straight forward. I of course agree that you might want uint32_least_t, but why not use 5u_least32 ? – RiaD Dec 03 '20 at 16:18
  • @RiaD -- re: `5u_least32` -- isn't that self-answering? Yes, I overlooked the point you make about ambiguous overloads. – Pete Becker Dec 03 '20 at 16:24
  • 1
    The fixed-width types come with a bunch of ambiguity anyway thanks to the interaction with the integer promotions. Does adding two `int32_t`s result in an `int32_t`? Not if you're on a system where `int` is 64-bit! –  Dec 03 '20 at 18:41
  • 7
    And does multiplying two large `uint16_t`s and storing the result in a `uint16_t` variable result in wraparound or undefined behavior? Integer math in C/C++ is a horrible mess. – plugwash Dec 03 '20 at 19:19
  • Multiplying two `uint16_t` of `0xFFFF` can indeed cause signed overflow (undefined behavior!) on a platform where int is 32 bits. See threads like https://stackoverflow.com/questions/27001604/32-bit-unsigned-multiply-on-64-bit-causing-undefined-behavior ; https://stackoverflow.com/questions/39964651/is-masking-before-unsigned-left-shift-in-c-c-too-paranoid ; https://stackoverflow.com/questions/24795651/whats-the-best-c-way-to-multiply-unsigned-integers-modularly-safely – Nayuki Dec 04 '20 at 20:42