Opened 15 years ago

Last modified 9 years ago

#1574 new Patches

operator<< for boost::posix_time::ptime ignores ostream flags

Reported by: adam@… Owned by: az_sw_dude
Milestone: Component: date_time
Version: Boost 1.45.0 Severity: Problem
Keywords: Cc:

Description

Consider the following:

boost::posix_time::ptime a;

cout << "one " << 1 << endl;
cout.clear(ios::failbit);
cout << "two " << 2 << endl;
cout << "time " << a << endl;
cout << "three" << 3 << endl;
cout.clear(ios::goodbit);
cout << "four " << 4 << endl;

Since cout should not produce output when ios::failbit is set, one would expect the output to be:

one 1
four 4

However, the output is:

one 1
not-a-date-timefour 4

Attachments (4)

ptime-operator.cpp (1.1 KB ) - added by christian.stimming@… 12 years ago.
Test case for this bug: Due to the error, in the second line the date still appears even though it shouldn't have been printed because of the ios::failbit.
fix-ptime-operator-bug1574.patch (1.3 KB ) - added by christian.stimming@… 12 years ago.
Patch for fixing this bug by querying ostream::fail() before doing anything in the operator<< of ptime and time_duration
fix-ptime-operator-2nd-bug1574.patch (1.9 KB ) - added by christian.stimming@… 12 years ago.
Better patch for this error which (after reading my Stroustrup again) is using the ostream's sentry constructor to check for potential failbits.
boost-date_time-1574.patch (6.6 KB ) - added by Dean Michael Berris 12 years ago.
Applies cleanly to trunk 68583

Download all attachments as: .zip

Change History (18)

comment:1 by christian.stimming@…, 12 years ago

Version: Boost 1.34.1Boost 1.43.0

I second this bug. The error still exists in boost-1.43.0. I'll attach a test case and a patch that fixes the bug by querying ostream::fail() before doing anything in the operator<<.

by christian.stimming@…, 12 years ago

Attachment: ptime-operator.cpp added

Test case for this bug: Due to the error, in the second line the date still appears even though it shouldn't have been printed because of the ios::failbit.

by christian.stimming@…, 12 years ago

Patch for fixing this bug by querying ostream::fail() before doing anything in the operator<< of ptime and time_duration

by christian.stimming@…, 12 years ago

Better patch for this error which (after reading my Stroustrup again) is using the ostream's sentry constructor to check for potential failbits.

comment:2 by Katie Chan, 12 years ago

Type: BugsPatches

comment:3 by Katie Chan, 12 years ago

The most recent patch when applied to 1.45 does not produce the "expected output".

comment:4 by Katie Chan, 12 years ago

Type: PatchesBugs

comment:5 by christian.stimming@…, 12 years ago

I don't understand ktchan's comment here. When compiling the attached example ptime-operator.cpp with any current boost (1.43, 1.45, SVN trunk; it doesn't matter which one), the output is

Should appear: Text. And Date: 2010-Dec-21 14:12:24.398138 Boost v104300
2010-Dec-21 14:12:24.398138
This line should appear (but no single date above): Text. And Date: 2010-Dec-21 14:12:24.398138

which is erroneous - the second line should have been empty. After applying the attached second patch fix-ptime-operator-2nd-bug1574.patch, the output is

Should appear: Text. And Date: 2010-Dec-21 14:12:32.328110 Boost v104300

This line should appear (but no single date above): Text. And Date: 2010-Dec-21 14:12:32.328110

which is the correct and expected output. Can you please apply the patch?

comment:6 by christian.stimming@…, 12 years ago

Type: BugsPatches
Version: Boost 1.43.0Boost 1.45.0

comment:7 by Katie Chan, 12 years ago

Hmm, my bad. I swear that when I tested it last time round, the output wasn't what was expected. :?

comment:8 by Rob Stewart, 12 years ago

The patch looks good except for the ill-formed identifiers with double underscores. I also find "cerb" to be nonsensical. The following changes would be better:

Instead of:

typedef std::basic_ostream<CharT, TraitsT> __ostream_type;
typename __ostream_type::sentry cerb(os);
if (cerb)

Use this:

typename std::basic_ostream<CharT, TraitsT>::sentry ready(os);
if (ready)

comment:9 by christian.stimming@…, 12 years ago

Feel free to commit the patch in the changed form you explained. However, the form I submitted was copied verbatim from gcc's STL, on Linux available in the file /usr/include/c++/4.4/bits/ostream_insert.h line 77ff.

I don't know specific reasons for choosing the form I copied from there, so feel free to implement it differently in boost. But if you ask me, I'd stick to the form proposed by gcc's STL.

comment:10 by Steven Watanabe, 12 years ago

The reason the STL uses is exactly the reason that we can't use it. Identifiers containing a double underscore are reserved to the implementation (i.e. the compiler and standard library) for any use.

comment:11 by Dean Michael Berris, 12 years ago

After looking at the ticket comments above I've made some modifications to make it a little more palatable playing nicely with the standard's forbidding the use of double underscores in identifiers that are not defined by the implementation. Please see the attached new modified patch.

by Dean Michael Berris, 12 years ago

Attachment: boost-date_time-1574.patch added

Applies cleanly to trunk 68583

comment:12 by christian.stimming@…, 11 years ago

Error still present in boost-1.46 and also still SVN trunk. Any news on applying the patch?

comment:13 by christian.stimming@…, 10 years ago

Error still present in boost-1.52 and also still SVN trunk. Any news on applying the patch?

comment:14 by christian.stimming@…, 9 years ago

Error still present in boost-1.53 and also still SVN trunk. Any news on applying the patch?

Note: See TracTickets for help on using tickets.