char_traits<char>::eof() 在 sizeof(int) == 1 的平台中如何编码?

The*_*Vee 7 c++ language-lawyer

我在 C++ 标准中找到了这些摘录(引自 N4687,但它可能永远存在):

\n\n

[字符.特征.typedefs]

\n\n
\n

对于某个字符容器类型char_type,相关的容器类型INT_T应该是能够表示相应char_type值转换的所有有效字符的类型或类,以及文件结束值eof()

\n
\n\n

[人物特征要求]

\n\n
\n

表达:X::eof()

\n\n

类型:X::int_type

\n\n

返回: 一个e适用X::eq_int_type(e,X::to_int_type(c))false所有 value 的值c

\n
\n\n

\n\n
\n

表达:X::eq_int_type(e,f)

\n\n

类型:bool

\n\n

返回:对于所有cdX::eq(c,d)等于X::eq_int_type(X::to_int_type(c), X::to_int_type(d))(...)

\n
\n\n

\n\n
\n

cd表示类型 的值CharT;(...); ef表示类型的值X::int_type

\n
\n\n

[char.traits.specializations.char]

\n\n
\n
using char_type = char;\nusing int_type = int;\n
Run Code Online (Sandbox Code Playgroud)\n
\n\n

[基础.基础]

\n\n
\n

Plain charsigned char、 和unsigned char是三种不同的类型,统称为窄字符类型。(...) A char、 asigned char和 anunsigned char占用相同的存储量并具有相同的对齐要求 (...) 对于窄字符类型,对象表示的所有位都参与值表示。(...) 对于无符号窄字符类型,值表示的每个可能的位模式都代表一个不同的数字。

\n
\n\n

\n\n
\n

有五种标准有符号整数类型: \xe2\x80\x9c signed char\xe2\x80\x9d、\xe2\x80\x9c short int\xe2\x80\x9d、\xe2\x80\x9c int\xe2\x80\x9d、\xe2\ x80\x9c long int\xe2\x80\x9d 和 \xe2\x80\x9c long long int\xe2\x80\x9d。在此列表中,每种类型至少提供与其前面的列表一样多的存储空间。

\n
\n\n

sizeof(int) == 1我在周围的文字中没有发现任何阻碍。这显然不是大多数现代平台的情况,其中是 4 或 8,但在cppreferencesizeof(int)中明确用作示例:

\n\n
\n

注意:这允许极端情况,其中字节大小为 64 位,所有类型(包括 char)都是 64 位宽,并且 sizeof 对每种类型返回 1。

\n
\n\n

问题

\n\n

如果int与 一样大char,则标准不会为前者的任何对象表示留下太多空间,这些空间将与后者的所有值(通过 )进行比较,只留下一些极端情况(例如存在于但映射到into_int_type中的负零)不太可能在硬件中有效实现。此外,对于P0907,它似乎甚至不允许任何两个不同的位串表示相同的值,从而迫使它具有 2^(bitsize) 不同的值,并且关闭每个可能的漏洞。signed charINT_MINintsigned charint

\n\n

在这样的平台上,如何才能符合要求呢std::char_traits<char>我们是否有此类平台的真实示例以及相应的实现?

\n

Bri*_*ian 2

例如,假设我们有一个平台,其中char是签名的且长度为 32 位,并且int也是。使用以下定义可以满足所有要求,其中Xstd::char_traits<char>

  • X::eqX::eq_int是简单的相等比较;
  • X::to_char_type返回其参数的值;
  • X::eof返回 -1,并且
  • X::to_int_type(c)c,除非c是 -1,在这种情况下它是 -2。

-1 到 -2 的映射保证X::eq_int_type(X::eof(), X::to_int_type(c))对所有 都是 false ,这是根据 C++20 表 69 的c要求。X::eof

这可能对应于一种实现,其中 -1 和 -2 (甚至可能是所有负数)是“无效”字符值,,它们存储在 a 中是完全合法的char,但从文件读取永远不会产生 a具有这样的值的字节。当然,只要您愿意接受无法区分“下一个字符是 -1”和“”的事实,就没有什么可以阻止您编写产生此类“无效”值的自定义流缓冲区。我们已经到了流的尽头”。

此实现的唯一可能问题是要求X::to_char_type(e)它等于

如果对某些人来说cX::eq_int_type(e,X::to_int_type(c))true; c其他一些未指定的值。

这可以理解为暗示如果c存在这样的东西,那么它是独一无二的。当为 -2 时,就会违反这一点e,因为c这里可能是 -1 或 -2。

如果我们假设需要唯一性,那么我认为没有任何可能的解决方案。