Does the standard guarantee that uint8_t, int8_t, and char are all unique types?
Asked Answered
M

2

6

It seems the following is guaranteed to pass (asked already here):

#include <type_traits>
static_assert(!std::is_same_v<char, signed char>);
static_assert(!std::is_same_v<char, unsigned char>);

To quote cppreference

[char] has the same representation and alignment as either signed char or unsigned char, but is always a distinct type

Is it also guaranteed that int8_t and uint8_t are defined in terms of the explicitly signed types not defined in terms of char, and therefore also form a set of 3 distinct types with char?

#include <cstdint>
#include <type_traits>
static_assert(!std::is_same_v<char, int8_t>);
static_assert(!std::is_same_v<char, uint8_t>);
Mediaeval answered 29/8, 2019 at 7:5 Comment(1)
I wouldn't expect standard to specify things which are hardly related, that would smell to me as over-specified. (and I somehow fail to see how int8/uint8 relate to char, except that char is highly likely represented by 8 bits too and you can cast between them safely, but none of that seems to me relevant to make the types same/non-same by standard.Inoue
T
8

On your first point, yes, char, signed char, and unsigned char must always be distinct types.

On the second point, int8_t and uint8_t might be or might not be the same type as a char (or its signed or unsigned variants); i.e. there is no guarantee for or against.

Trinidadtrinitarian answered 29/8, 2019 at 7:6 Comment(0)
B
8

The fixed-width types are implementation-defined aliases. The (u)int8_t types are NOT guaranteed to be aliases for any of the fundamental char types at all. They are only guaranteed to be (un)signed 8-bit integer types. They MAY be aliases for (un)signed char, or they MAY be aliases for vendor-specific types, such as (un)signed __int8. It is up to each compiler vendor to decide what aliases best suits their implementation.

Blent answered 29/8, 2019 at 7:14 Comment(4)
I updated my question - what I'm hoping for is a guarantee that they are not aliases of unqualified char, because if they are I cannot specialize a template for char without also matching one of those types.Mediaeval
@Eric: No, there's no such guarantee: typedef char uint8_t; would do if char is unsigned, although I'd conject that a sensible implementation would use typedef unsigned char uint8_t;.Trinidadtrinitarian
To some extent, I'd argue it's the job of the standard to require a sensible implementation :). I suppose this is a very small thorn to spend committee time on though...Mediaeval
@Mediaeval what's the precise issue, if the char specialization covers also one of those two types? Does it clash, if you add another two specializations for uint8_t and int8_t? That would sound like real problem to me, but I would expect the compiler then to treat that ambiguity by checking for the specific type of the specialization and treating all three of them as different type. clang 8.0.0 seems to do that: godbolt.org/z/gphsmB (for me this looks then as no-issue, because if your code wants to specialize for some type, it can)Inoue

© 2022 - 2024 — McMap. All rights reserved.