[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi] Unexpected gcc diagnostic
From: |
Greg Chicares |
Subject: |
[lmi] Unexpected gcc diagnostic |
Date: |
Tue, 6 Apr 2021 15:41:21 +0000 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.9.0 |
Vadim--What do you make of this? Building for i686-w64-mingw32
with `i686-w64-mingw32-gcc -dumpfullversion` = "10-win32" on
our corporate server, we observe:
In file included from /opt/lmi/src/lmi/any_member.hpp:65,
from /opt/lmi/src/lmi/mec_state.hpp:27,
from /opt/lmi/src/lmi/ihs_irc7702a.hpp:28,
from /opt/lmi/src/lmi/ihs_irc7702a.cpp:30:
/opt/lmi/src/lmi/ihs_irc7702a.cpp: In member function ‘double
Irc7702A::DetermineLowestBft() const’:
/opt/lmi/src/lmi/ihs_irc7702a.cpp:1306:32: error: zero as null pointer constant
[-Werror=zero-as-null-pointer-constant]
1306 | LMI_ASSERT(Bfts.begin() <= last_bft_in_test_period);
| ^~~~~~~~~~~~~~~~~~~~~~~
/opt/lmi/src/lmi/assert_lmi.hpp:56:12: note: in definition of macro ‘LMI_ASSERT’
56 | if(condition) \
| ^~~~~~~~~
But the build succeeds with no warnings on my own PC,
using "10-win32" (possibly a slightly later version
than the same-versioned compiler on the server). And I
imagine we'd already know if github CI got this warning.
The code is:
double Irc7702A::DetermineLowestBft() const
{
LMI_ASSERT(0 <= TestPeriodLen && 0 <= TestPeriodDur);
std::vector<double>::const_iterator last_bft_in_test_period = std::min
(Bfts.end()
,Bfts.begin() + std::min(TestPeriodLen, TestPeriodDur)
);
LMI_ASSERT(Bfts.begin() <= last_bft_in_test_period);
// TAXATION !! This is harmful for inforce if inforce history is unreliable:
LowestBft = *std::min_element(Bfts.begin(), last_bft_in_test_period);
return LowestBft;
}
I reason that the assertion is superfluous and can never fire:
- TestPeriodLen and TestPeriodDur are both 'int', and
they've already been asserted to be nonnegative;
- begin() plus the sum of two nonnegative ints cannot be
less than begin();
- end() cannot be less than begin();
- the min() of two things cannot be less than begin() when
both things are not less than begin().
But that's dynamic analysis; is the compiler is performing
static analysis here? Either way, how can it conclude that
there's a null pointer here? A begin() iterator can't be
zero, and neither can begin() plus a nonnegative int, so
I think 'last_bft_in_test_period' can never be zero.
I'm tempted to remove the assertion, because it seems to
have no value; but I don't want to delete a line because
of a diagnostic that I don't understand; and, even if it
provably can never fire, the proof is complicated enough
not to see at a glance, whereas the assertion clearly
protects us against a segfault in std::min_element().
I imagine std::vector::const_iterator is of unsigned type,
and I know compilers warn about comparisons like
unsigned int x;
LMI_ASSERT(0 <= x);
^^^^^^ must always be true
but I don't see how that could be the explanation of
the diagnostic above: begin() cannot have the value zero
because it's intended to be dereferenced.
- [lmi] Unexpected gcc diagnostic,
Greg Chicares <=