Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does operator>> on complex<double> not set eofbit if it reaches EOF?

I'm trying to read as many std::complex<double> as possible from a file (or any std::istream). If the operation fails, I check for ios::eof(). If it hasn't been set, I assume that there was an error in parsing the data, and I can report to the user that the input file has errors. This scheme works for double, but somehow it fails on complex numbers. Why?

Here is some code to reproduce the problem:

std::istringstream istr("4 1.2");
std::complex<double> val;

while( istr >> val )
        std::cout << " val = " << val << std::endl;

std::cout << "flags: eof=" << istr.eof() << " fail=" << istr.fail() << " bad=" << istr.bad() << std::endl;

The output is

 val = (4,0)
 val = (1.2,0)
 flags: eof=0 fail=1 bad=0

If I replace std::complex<double> with double, it works as expected, yielding

 val = 4
 val = 1.2
 flags: eof=1 fail=1 bad=0

This problem occurs with libstdc++, but it seems to work with libc++:

run on coliru with g++

run on coliru with clang++ and libc++

EDIT I found a bug report from 2013 but the problem still seems to be there, and the library is quite common. Is there a way for me to make it work for anybody without having to write my own parser?

like image 808
dennis Avatar asked Jun 16 '16 12:06

dennis


1 Answers

It stems from standard wording:

[complex.ops]
12 Effects: Extracts a complex number x of the form: u, (u), or (u,v), where u is the real part and v is the imaginary part (27.7.2.2).
13 Requires: The input values shall be convertible to T. If bad input is encountered, calls is.setstate(ios_base::failbit) (which may throw ios::failure (27.5.5.4)).
14 Returns: is.
15 Remarks: This extraction is performed as a series of simpler extractions. Therefore, the skipping of whitespace is specified to be the same for each of the simpler extractions.

In particular it does not specify that it should set eofbit in any case. Even remark does not specify what operations are performed and what their semantic is. There is a Defect Report about it, which suggest resolution by specifying semantic of operation and, if we are lucky, it will make its way to C++17.

like image 67
Revolver_Ocelot Avatar answered Nov 08 '22 18:11

Revolver_Ocelot