When specifying the command line options -Wstrict-overflow=4
and -O3
, extracting a timepoint (e.g. std::chrono::local_seconds
) from a stream object triggers some warnings from GCC (v14.1). Inserting a timepoint to a stream object triggers some warnings as well.
This is not the case with Clang though. It doesn’t show any warnings despite specifying -stdlib=libstdc++
.
On GCC, the warnings appear even with -O1
or O2
but not with -Og
or -O0
or -Os
.
A minimal example:
#include <chrono>
#include <iostream>
int main()
{
std::chrono::local_seconds tp;
std::cin >> std::chrono::parse( "%F %T", tp );
if ( std::cin )
std::cout << tp << 'n';
}
All of the warnings are related to signed overflow somehow. But they all disappear when -Wstrict-overflow=2
is used instead.
Should this be concerning?
The warning message:
<source>: In member function 'std::basic_istream<_CharT2, _Traits2>& std::chrono::__detail::_Parser<_Duration>::operator()(std::basic_istream<_CharT2, _Traits2>&, const _CharT*, std::__cxx11::basic_string<_CharT2, _Traits2, _Alloc>*, std::chrono::minutes*) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; _Duration = std::chrono::duration<long int>]':
<source>:12:1: warning: assuming signed overflow does not occur when changing X +- C1 cmp C2 to X cmp C2 -+ C1 [-Wstrict-overflow]
12 | }
| ^
<source>: In constructor 'constexpr std::chrono::hh_mm_ss<_Duration>::hh_mm_ss(_Duration) [with _Duration = std::chrono::duration<long int>]':
<source>:12:1: warning: assuming signed overflow does not occur when determining that expression is always non-negative [-Wstrict-overflow]
In file included from /opt/compiler-explorer/gcc-14.1.0/include/c++/14.1.0/chrono:41,
from <source>:2:
In function 'constexpr typename std::common_type<std::chrono::duration<_Rep1, _Period1>, std::chrono::duration<_Rep2, _Period2> >::type std::chrono::operator-(const duration<_Rep1, _Period1>&, const duration<_Rep2, _Period2>&) [with _Rep1 = long int; _Period1 = std::ratio<1>; _Rep2 = long int; _Period2 = std::ratio<60>]',
inlined from 'constexpr std::chrono::hh_mm_ss<_Duration>::hh_mm_ss(_Duration, bool) [with _Duration = std::chrono::duration<long int>]' at /opt/compiler-explorer/gcc-14.1.0/include/c++/14.1.0/chrono:2338:55,
inlined from 'constexpr std::chrono::hh_mm_ss<_Duration>::hh_mm_ss(_Duration) [with _Duration = std::chrono::duration<long int>]' at /opt/compiler-explorer/gcc-14.1.0/include/c++/14.1.0/chrono:2369:49,
inlined from 'static decltype(auto) std::__format::__formatter_chrono<_CharT>::_S_hms(const _Tp&) [with _Tp = std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long int> >; _CharT = char]' at /opt/compiler-explorer/gcc-14.1.0/include/c++/14.1.0/bits/chrono_io.h:1433:21:
/opt/compiler-explorer/gcc-14.1.0/include/c++/14.1.0/bits/chrono.h:716:41: warning: assuming signed overflow does not occur when determining that expression is always non-negative [-Wstrict-overflow]
716 | return __cd(__cd(__lhs).count() - __cd(__rhs).count());
| ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
<source>: In static member function 'static decltype(auto) std::__format::__formatter_chrono<_CharT>::_S_hms(const _Tp&) [with _Tp = std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long int> >; _CharT = char]':
<source>:12:1: warning: assuming signed overflow does not occur when determining that expression is always non-negative [-Wstrict-overflow]
12 | }
| ^
<source>:12:1: warning: assuming signed overflow does not occur when determining that expression is always non-negative [-Wstrict-overflow]
In function 'constexpr typename std::common_type<std::chrono::duration<_Rep1, _Period1>, std::chrono::duration<_Rep2, _Period2> >::type std::chrono::operator-(const duration<_Rep1, _Period1>&, const duration<_Rep2, _Period2>&) [with _Rep1 = long int; _Period1 = std::ratio<1>; _Rep2 = long int; _Period2 = std::ratio<60>]',
inlined from 'constexpr std::chrono::hh_mm_ss<_Duration>::hh_mm_ss(_Duration, bool) [with _Duration = std::chrono::duration<long int>]' at /opt/compiler-explorer/gcc-14.1.0/include/c++/14.1.0/chrono:2338:55,
inlined from 'constexpr std::chrono::hh_mm_ss<_Duration>::hh_mm_ss(_Duration) [with _Duration = std::chrono::duration<long int>]' at /opt/compiler-explorer/gcc-14.1.0/include/c++/14.1.0/chrono:2369:49,
inlined from 'typename _FormatContext::iterator std::__format::__formatter_chrono<_CharT>::_M_format_to_ostream(const _Tp&, _FormatContext&, bool) const [with _Tp = std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long int> >; _FormatContext = std::basic_format_context<std::__format::_Sink_iter<char>, char>; _CharT = char]' at /opt/compiler-explorer/gcc-14.1.0/include/c++/14.1.0/bits/chrono_io.h:720:16:
/opt/compiler-explorer/gcc-14.1.0/include/c++/14.1.0/bits/chrono.h:716:41: warning: assuming signed overflow does not occur when determining that expression is always non-negative [-Wstrict-overflow]
716 | return __cd(__cd(__lhs).count() - __cd(__rhs).count());
| ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
<source>: In member function 'typename _FormatContext::iterator std::__format::__formatter_chrono<_CharT>::_M_format_to_ostream(const _Tp&, _FormatContext&, bool) const [with _Tp = std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long int> >; _FormatContext = std::basic_format_context<std::__format::_Sink_iter<char>, char>; _CharT = char]':
<source>:12:1: warning: assuming signed overflow does not occur when determining that expression is always non-negative [-Wstrict-overflow]
12 | }
| ^
<source>:12:1: warning: assuming signed overflow does not occur when determining that expression is always non-negative [-Wstrict-overflow]
In function 'constexpr unsigned int std::chrono::__detail::__add_modulo(unsigned int, _Tp) [with unsigned int __d = 7; _Tp = long int]',
inlined from 'static constexpr std::chrono::weekday std::chrono::weekday::_S_from_days(const std::chrono::days&)' at /opt/compiler-explorer/gcc-14.1.0/include/c++/14.1.0/chrono:973:58,
inlined from 'constexpr std::chrono::weekday::weekday(const std::chrono::sys_days&)' at /opt/compiler-explorer/gcc-14.1.0/include/c++/14.1.0/chrono:986:29,
inlined from 'std::basic_istream<_CharT2, _Traits2>& std::chrono::__detail::_Parser<_Duration>::operator()(std::basic_istream<_CharT2, _Traits2>&, const _CharT*, std::__cxx11::basic_string<_CharT2, _Traits2, _Alloc>*, std::chrono::minutes*) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; _Duration = std::chrono::duration<long int>]' at /opt/compiler-explorer/gcc-14.1.0/include/c++/14.1.0/bits/chrono_io.h:4156:18:
/opt/compiler-explorer/gcc-14.1.0/include/c++/14.1.0/chrono:533:40: warning: assuming signed overflow does not occur when changing X +- C1 cmp C2 to X cmp C2 -+ C1 [-Wstrict-overflow]
533 | auto const __offset = __y >= 0 ? _Up(0) : __modulo_offset<__d, _Tp>();
| ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Is this a flaw in GCC? Like some false positive? Because this warning option doesn’t annoy other parts of my program. Only the I/O parts.