Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a portable literal suffix for int64_t and similar types?

I was trying to understand std::variant:

#include <cstdint>
#include <variant>

std::variant<int64_t, double> v;

I wanted to assign an int64_t variant: v = 5L; That compiles on x86_64 because int64_t is long. But it does not compile on arm, because int64_t is long long. The type deduction has now two equal choices between int64_t and double to convert my number to, so it declines. With variant<int64_t, string> I wouldn't even have noticed the conversion, because then there is only one available and the compiler would have accepted it.

Similar issue with: v = 5LL; Now arm / 32 bit is fine, but x86_64 not anymore.

I get this compiling on both platforms but this is (sometimes) a type conversion with potential side-effects I am not able to foresee: v = int64_t(5LL);. Without the LL I wouldn't even be able to express values outside 32bit int.

The INT64_C macro seems to be the most portable and safest way to express this: v = INT64_C(5); But this not nice to read and write anymore.

Is there a similar literal suffix like L/LL for int64_t that is portable?

like image 435
ProgrammingAtDawn Avatar asked Dec 22 '20 10:12

ProgrammingAtDawn


People also ask

What is the suffix of Integer literals?

Integer literals can have a type suffix and a multiplier suffix. The type of an integer literal is determined by its value, the type suffix, and the numeric multiplier suffix.

What is the difference between int64_t and long a long?

A long on some systems is 32 bits (same as an integer), the int64_t is defined as a 64 bit integer on all systems (otherwise known as a long long). Portability may be affected using long, but using int64_t looks like it was created to increase portability.

What is the suffix for int in C++?

Suffixes: They are represented in many ways according to their data types. int:- No suffix are required because integer constant are by default assigned as int data type. unsigned int: character u or U at the end of integer constant.

What is integer literal in C++?

Integer literal in C/C++ (Prefixes and Suffixes) Integer literal is a type of literal for an integer whose value is directly represented in source code.


1 Answers

No, there are no standard literals for fixed width integer aliases.

One potential workaround would be to use std::variant<long long, double> v;. Although long long theoretically isn't guaranteed to be exactly 64 bits (it may be wider, but not narrower), it is 64 bits on practically every system that supports long long today. The benefit is that long long of course has a standard literal. The potential drawback is that the size situation may theoretically change in future.

A more general solution is to give up on using a literal suffix, and instead use a cast: v = static_cast<int64_t>(5);.

Another solution is to create a user defined literal as shown in this answer linked in comments:

constexpr std::int64_t operator "" _int64(unsigned long long v)
{ return static_cast<std::int64_t>(v); }

There is a proposal to add literals such as this to the standard library: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1280r2


On a related note, there is a proposal to add literals for std::size_t and std::ptrdiff_t. That proposal suggests core language literals instead of a standard library literals: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0330r3

like image 86
eerorika Avatar answered Sep 18 '22 15:09

eerorika