C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Shorter fixed-width integer types

From: Yexuan Xiao <bizwen_at_[hidden]>
Date: Wed, 2 Jul 2025 07:26:12 +0000
The growing demand for handling massive data over the past decade has made more people aware of the limitations of int. For example, C# 9.0 added the keywords nint and nuint as aliases for IntPtr and UIntPtr. A friend of mine working on C# at Microsoft complained this year that C#’s Span not using IntPtr was a flaw. Perhaps more people will recognize the benefits of semantic type aliases in the future (though JavaScript opted to solve the problem with BigInt and IntArray since it previously had no integer type at all and couldn’t define aliases).

When not used for serialization, int is no worse than u16, but also no better. Defining a set of fixed-width integer aliases implemented with _BitInt might be useful—though I don’t have enough experience with _BitInt to be sure. I’m somewhat concerned about its interoperability with templates and existing standard library facilities. Moreover, promoting _BitInt without causing confusion might be just as challenging as promoting semantic type aliases.
________________________________
From: Jan Schultke <janschultke_at_[hidden]>
Sent: Wednesday, July 2, 2025 11:58
To: std-proposals_at_[hidden] <std-proposals_at_[hidden]>
Cc: Yexuan Xiao <bizwen_at_[hidden]>
Subject: Re: [std-proposals] Shorter fixed-width integer types

Imagine one day you write a piece of software that uses 8 bits to store the length of a certain name. You carry this assumption across various modules of the software, so much so that int8_t is scattered everywhere in the code. Years later, you realize 8 bits are no longer sufficient, and you want your software to support longer names. At that point, you’ll find it extremely difficult because int8_t is used everywhere in the program, and you can’t distinguish whether it represents the length of a name or serves some other purpose. This was a very common issue in the last century.
Therefore, the correct approach is to define using nlength_t = uint8_t;, treating nlength_t as the type for name lengths. This way, you can quickly adjust its actual width without needing to discern its purpose. This is also why size_t is so important—it is designed to be as large as possible to handle as much data as needed.

I agree in principle that using semantic type aliases is better than using specific widths directly everywhere.

However, realistically speaking, you'll never get the C++ community to consistently use semantic aliasing. C++ is taught with int and float from the ground up; people are accustomed to using fundamental types directly. It won't ever fully catch on for the same reason almost everyone uses the <i> tag to make their text italic, rather than using <em>, <dfn>, <var>, or other semantic tags that render the same (by default) but carry more information. The outcome is the same, so it's hard to get people on board for rather abstract reasons.

Also, when a fixed-width integer appears for ABI reasons, or because your uint32_t represents four bytes to be deserialized in a protocol or file format, then that uint32_t can virally propagate into the rest of the program. You have to be quite consequential to define points where your uint32_t turns into index_type. Semantic aliasing is also a practice that's quite specific to C++. For example, Kotlin uses Int everywhere in the standard library, JavaScript uses number, Python uses int, etc.

Given the reality of the situation, we may as well provide shorthands like std::u8, but not for std::uint8_t as I've previously explained (_BitInt would be a better candidate).


Received on 2025-07-02 07:26:21