lmi
[Top][All Lists]
Advanced

[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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]