Subject: [Boost-bugs] [Boost C++ Libraries] #3606: One potential bug, and lots of warnings in DateTime
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2009-11-11 10:02:59
#3606: One potential bug, and lots of warnings in DateTime
--------------------------+-------------------------------------------------
Reporter: johnmaddock | Owner: az_sw_dude
Type: Bugs | Status: new
Milestone: Boost 1.42.0 | Component: date_time
Version: Boost 1.40.0 | Severity: Problem
Keywords: |
--------------------------+-------------------------------------------------
Boost.DateTime when compiled at high warning levels emits rather a lot of
warnings, at least one of which seems to indicate a genuine potential bug
and/or trap for the unwary. In addition these warnings are seen by
libraries like Boost.Thread which depend on DateTime, so the effect is not
limited to just DateTime itself.
I'm attaching a log of the build for msvc-9 (with /W4) and gcc-4.4.1 (with
-Wall -Wextra -pedantic) showing the warnings produced.
As to the potential bug, consider this warning:
{{{
d:\data\boost\trunk\boost/date_time/date_clock_device.hpp(41) : warning
C4244: 'argument' : conversion from 'int' to 'unsigned short', possible
loss of data
d:\data\boost\trunk\boost/date_time/date_clock_device.hpp(36) :
while compiling class template member function
'boost::gregorian::date::ymd_type
boost::date_time::day_clock<date_type>::local_day_ymd(void)'
with
[
date_type=boost::gregorian::date
]
gregorian\testdate_input_facet.cpp(257) : see reference to class
template instantiation 'boost::date_time::day_clock<date_type>' being
compiled
with
[
date_type=boost::gregorian::date
]
}}}
The problem here is that the integer argument representing the
day/month/year gets truncated to a short in the constructor of
greg_day/greg_month/greg_year. The problem here is manifold: first off I
can't find it documented anywhere what type the argument to a
day/month/year type should be (conceptually speaking) so it's hard to
justify an explicit type cast in generic code like this. More
importantly, the implicit cast taking place here can circumvent the error
checking inside the day/month/year type, consider:
{{{
int i = 0xf0001;
boost::gregorian::greg_day d(i);
}}}
You might expect this to throw since the value i is out of range, but it
doesn't because i gets truncated to the value 1 before the constructor is
called. Thus if these types are accidentally constructed with a garbage
value (whether within the DateTime headers, or in user code), the
construction can actually succeed :-(
I think one potential solution is to decouple error-checking from storage
type - for example if the constructor for greg_day was changed to a
template:
template <class Integer>
greg_day(Integer day_of_month);
and likewise for the underlying base type constructor, then we can error
check the actual argument passed, and only then cast it to the storage
type used. As a bonus, is there any reason why the storage type is a
short? Could it be an unsigned char? The latter would decrease the size
of a day/month/year type from 8 to 4 bytes.
Anyhow let me know if you need help fixing the other warnings - I stopped
when I saw this one, because it didn't look like the usual spurious
warning!
Cheers, John.
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/3606> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:01 UTC