标准是否保证 uint8_t、int8_t 和 char 三种类型都是唯一的?

6

看起来以下内容是保证通过的(已经在这里询问过):

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

引用cppreference

[char]具有与signed charunsigned char相同的表示和对齐方式,但始终是不同的类型。

是否也保证int8_tuint8_t是在明确有符号类型的基础上定义的,而不是在char的基础上定义的,因此它们与char一起形成了一组3个不同的类型?

#include <cstdint>
#include <type_traits>
static_assert(!std::is_same_v<char, int8_t>);
static_assert(!std::is_same_v<char, uint8_t>);

我不会期望标准规定那些与之关系微乎其微的事情,这对我来说似乎是过度规定。 (而且我不知道int8 / uint8如何与char相关,除了char很可能也由8位表示,并且您可以安全地在它们之间进行转换,但是在我的看来,这些都不相关,无法使类型按照标准相同/不同。) - Ped7g
2个回答

8

关于第一个观点,是的,charsigned charunsigned char必须始终是不同类型。

关于第二个观点,int8_tuint8_t可能与char(或其signedunsigned变体)相同,也可能不相同;即没有保证或反对。


8
固定宽度类型是“实现定义”的别名。 (u)int8_t类型并没有保证一定是任何基本char类型的别名。 它们只保证是(无)符号8位整数类型。 它们可能是(无)符号字符的别名,也可能是供应商特定类型的别名,例如(无)符号__int8。 每个编译器供应商都可以决定哪些别名最适合他们的实现。

我更新了我的问题 - 我希望得到的保证是它们不是未经限定的 char 的别名,因为如果是这样,我就无法为 char 特化一个模板,而不匹配其中一种类型。 - Eric
1
@Eric:不,没有这样的保证:如果charunsigned,则typedef char uint8_t;就可以了,尽管我猜测一个明智的实现会使用typedef unsigned char uint8_t; - Bathsheba
在某种程度上,我认为标准的工作是“要求”合理的实现 :)。虽然我想这只是一个很小的问题,不值得委员会花费太多时间... - Eric
@Eric,如果char特化也覆盖了这两种类型之一,那么确切的问题是什么?如果您为uint8_tint8_t添加另外两个特化,会发生冲突吗?对我来说,这听起来像是一个真正的问题,但我期望编译器通过检查特化的具体类型并将它们三个视为不同的类型来处理这种歧义。clang 8.0.0似乎就是这样做的:https://godbolt.org/z/gphsmB(对我来说,这看起来就像没有问题,因为如果您的代码想要为某些类型进行特化,它可以这样做) - Ped7g

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接