Date: Tue, 1 Jul 2025 19:24:27 +0300
Aliasing stdint types like uint16_t to shorter names like u16 has become
a very common practice. This trend has influenced other modern languages
like Rust, Zig, Cpp2, Carbon and Odin to adopt this. On GitHub, u8 alone
has lead to the same ~6k lines of code (counted with
https://github.com/search?q=%22typedef+uint8_t+u8%22+language%3AC%2B%2B++NOT+is%3Afork&type=code
and
https://github.com/search?q=%22using+u8+%3D%22+language%3AC%2B%2B++NOT+is%3Afork&type=code).
These names (int*_t) while precise, are quite verbose and cumbersome to
use, especially in codebases where dealing with low-level code is the
norm such as binary loaders or networking tools.
I propose the following to be included in <cstdint>, a approach which
has been inspired by std::literals:
namespace std {
namespace ints {
using i8 = int8_t;
using u8 = uint8_t;
using i16 = int16_t;
using u16 = uint16_t;
using i32 = int32_t;
using u32 = uint32_t;
using i64 = int64_t;
using u64 = uint64_t;
using iN = intN_t;
using uN = uintN_t;
}
}
The typical usage of this would be as follows:
using namespace std::ints;
struct SomeFileFormatHeader {
u16 magic;
u32 checksum;
u32 num_entries;
// etc...
}
I have considered putting those in the same namespace as int*_t but that
would break existing code that already defines those types using the
help of stdint.
a very common practice. This trend has influenced other modern languages
like Rust, Zig, Cpp2, Carbon and Odin to adopt this. On GitHub, u8 alone
has lead to the same ~6k lines of code (counted with
https://github.com/search?q=%22typedef+uint8_t+u8%22+language%3AC%2B%2B++NOT+is%3Afork&type=code
and
https://github.com/search?q=%22using+u8+%3D%22+language%3AC%2B%2B++NOT+is%3Afork&type=code).
These names (int*_t) while precise, are quite verbose and cumbersome to
use, especially in codebases where dealing with low-level code is the
norm such as binary loaders or networking tools.
I propose the following to be included in <cstdint>, a approach which
has been inspired by std::literals:
namespace std {
namespace ints {
using i8 = int8_t;
using u8 = uint8_t;
using i16 = int16_t;
using u16 = uint16_t;
using i32 = int32_t;
using u32 = uint32_t;
using i64 = int64_t;
using u64 = uint64_t;
using iN = intN_t;
using uN = uintN_t;
}
}
The typical usage of this would be as follows:
using namespace std::ints;
struct SomeFileFormatHeader {
u16 magic;
u32 checksum;
u32 num_entries;
// etc...
}
I have considered putting those in the same namespace as int*_t but that
would break existing code that already defines those types using the
help of stdint.
Received on 2025-07-01 16:24:31