g++/stdlib++与clang++/libc++读取double流的行为差异及正确性求证
g++/stdlib与clang/libc++读取double类型的行为差异及标准合规性
g搭配stdlib,与clang搭配libc在从流读取double类型时存在行为差异,以下是最小复现代码:
#include <assert.h> #include <iostream> #include <string> #include <sstream> int main(int argv, char** argc) { std::string line = "1.1", line2 = "1.1X"; std::istringstream iss(line), iss2(line2); double x; assert(iss >> x); std::cout << x << "\n" << std::flush; assert(iss2 >> x); std::cout << x << "\n"; return 0; }
clang搭配libc的编译运行结果
>clang++ -stdlib=libc++ reading_double.cc -o reading_double >./reading_double 1.1 reading_double: reading_double.cc:11: int main(int, char **): Assertion `iss2 >> x' failed. Aborted (core dumped) >clang --version Ubuntu clang version 18.0.0 (++20231004042239+548d67a0393c-1~exp1~20231004042400.1224) Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: /usr/bin
g搭配stdlib的编译运行结果
>g++ reading_double.cc -o reading_double >./reading_double 1.1 1.1 >g++ --version g++ (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0 Copyright (C) 2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
标准合规性分析
根据C++标准规定,使用operator>>读取浮点数时,会跳过前导空白字符,然后读取尽可能多的有效浮点数字符组成合法的浮点数表示。只要成功读取了至少一个有效浮点数字符(即完成了浮点数的解析),即使流中还有剩余的非数字字符,读取操作也应成功,流的状态标记为正常,而非失败。
在示例中,字符串"1.1X"的前缀"1.1"是完全合法的double类型表示,因此读取操作必须成功,将x赋值为1.1,同时流的位置停留在字符'X'处。
由此可见,g++/stdlib的行为符合C标准,而clang++/libc++的行为不符合标准——它错误地将存在有效浮点数前缀但后续有非数字字符的情况判定为读取失败。
内容的提问来源于stack exchange,提问作者David Lehavi
相关产品推荐
相关产品推荐

