0

我在玩 C++17 std::byte,遇到了一些奇怪的行为。我不知道这是不是有意的,或者我做错了什么。

std::byte test_byte{80};
std::cout << "Test: " << std::to_integer<uint8_t>(test_byte) << " vs " << std::to_integer<uint16_t>(test_byte) << "\n";

这将打印出:

Test: P vs 80

然后我查了一下ASCII表,发现大写P的数值是80。

我的问题是这是预期的还是错误的,或者甚至是特定于操作系统/编译器的?

运行 Windows 10 并使用 VS Build Tools 进行编译。

4

2 回答 2

3

我的问题是这是否是预期的

有点。

如果这是一个错误

不,这只是 API 中的一点不便。

甚至可能是特定于操作系统/编译器的?

不。

这与std::to_integer. 问题是系统上 8 位宽的整数类型恰好是 ( unsigned) char。而这个整数类型恰好也是字符类型。

字符流对作为字符的整数与非字符类型的整数的处理方式不同。具体来说,行为是打印由该整数编码的字符,而不是值的文本表示。

解决方案是将其转换uint8_t为更广泛的整数类型,例如unsigned int在将其插入字符流之前。

于 2020-07-30T10:50:56.123 回答
0

比较这两行代码:

unsigned char c = 80;

std::cout << c << '\n';
std::cout << +c << '\n';

这应该可以帮助您了解正在发生的事情!

在第一种情况下,它会根据架构和平台(硬件制造商:Intel、AMD 等,以及 Windows、Mac、Linux 等)打印该值的ASCII字符甚至可能是该值的字符,其类型为正在使用...它甚至可能不打印任何内容并导致内部计算机的蜂鸣器发出哔哔声,具体取决于值...UNICODEstream_buf

在第二种情况下,它将实际值打印80到控制台。

这里发生的事情是由不同于常规或类型unsigned char的类解释,因为它是一种类型。你可能会也可能不会看到同样的效果,我对此不是 100% 确定,但我 100% 确定该类型。std::basic_streambufintegral signedunsignedcharsigned charunsigned char

在第二种情况下打印值的原因80是由于类型的unary operator+()前缀unsigned char。这会导致整数提升。

此特征或副作用将适用于任何和所有类型,无论是typedef还是aliased来自unsigned char

在您的情况下,您看到P被打印是因为您正在转换或转换为unsigned char类型,因为uint8_t它是unsigned char!

于 2020-07-30T15:16:49.230 回答