std::basic_istream::ignore 如果设置了 delim MSB 则会挂起

问题描述 投票:0回答:1

给出以下片段:

#include <iostream>
#include <sstream>

int main()
{
  std::stringstream str;
  str.put('a');
  str.put('\x80');
  str.put('a');

  str.ignore(32, '\x80'); // hangs
  std::cout << str.tellg() << "\n";
}

如果使用 gcc 编译,标记的行会挂起,汇编单步执行表示无限循环。我在不同的操作系统上尝试了GCC 5.4、6.3、8.2、9.2,结果是相同的。 在 wandbox 上,也尝试了 clang (可能是 libc++ 而不是 libstdc++ 附带的),它正常终止。

只有当ignore的第二个参数是设置了MSB的字符,并且流中前后至少有一个字符时,才会发生这种情况。这是 libstdc++ 中的错误,还是标准禁止非 ascii 分隔符?

c++ gcc stream libstdc++
1个回答
0
投票

没有签名溢出,但问题与签名与未签名有关。

istream::ignore(n, delim)
的内部使用
streambuf::sgetc()
检查下一个字符并将其与分隔符
delim
进行比较。
sgetc()
对于 EOF 返回 -1,否则返回非负值。这意味着当它到达
'\x80'
字符
sgetc()
时,将返回
(int)(unsigned char)'\x80'
,即 128,并且永远不会与
delim
进行比较,即 -128。

这是 GCC 的 libstdc++ 中的一个 bug,它应该将

delim
字符转换为非负
int_type
,以便可以将其与
sgetc()
返回的值进行比较。

© www.soinside.com 2019 - 2024. All rights reserved.