lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] Unexpected gcc diagnostic


From: Vadim Zeitlin
Subject: Re: [lmi] Unexpected gcc diagnostic
Date: Wed, 7 Apr 2021 12:27:36 +0200

On Wed, 7 Apr 2021 10:00:19 +0000 Greg Chicares <gchicares@sbcglobal.net> wrote:

GC> On 4/6/21 6:59 PM, Greg Chicares wrote:
GC> [...]
GC> >> GC>     LMI_ASSERT(Bfts.begin() <= last_bft_in_test_period);
GC> >> GC>     LowestBft = *std::min_element(Bfts.begin(), 
last_bft_in_test_period);
GC> > 
GC> > [...snip my rigorous proof of something that isn't quite what we want...]
GC> > 
GC> >>  All this is correct and holds even if Bfts vector is empty. However
GC> >> dereferencing the iterator returned by std::min_element() wouldn't be in
GC> >> this case, as it would return non-dereferencable Bfts.end() iterator. I'm
GC> >> not at all sure if it's worth checking for this, but I wanted to at least
GC> >> mention this for completeness.
GC> > 
GC> > Thanks: "<=" above isn't good enough; "<" would truly guard
GC> > the "*std::min_element" expression.
GC> 
GC> No, I misunderstood.

 Thanks for writing this because I thought I was misunderstanding something
myself, as I couldn't see why would the above be the right thing to do and
was going to return to it after getting some sleep as I didn't trust myself
yesterday evening. Admittedly, I didn't get that much sleep, but now it
doesn't matter because you've already confirmed that this didn't work and
so I don't have to explain why I think it wouldn't.

GC> I tried making the change I described above:
GC> 
GC> -    LMI_ASSERT(Bfts.begin() <= last_bft_in_test_period);
GC> +    LMI_ASSERT(Bfts.begin() < last_bft_in_test_period);
GC> 
GC> and that caused system-test failures.
GC> 
GC> The question is when it's okay to dereference this iterator:
GC>   LowestBft = *std::min_element(Bfts.begin(), last_bft_in_test_period);
GC> The answer is not whenever
GC>   Bfts.begin() < last_bft_in_test_period
GC> but, rather, whenever both
GC>   Bfts.begin() < Bfts.end()               [the vector is not empty], and
GC>   Bfts.begin() <= last_bft_in_test_period [the range is not insane]

 IMO the answer is whenever _either_

        Bfts.begin() < last_bft_in_test_period

_or_

        last_bft_in_test_period < Bfts.end()

I.e., by construction of last_bft_in_test_period we know that

        Bfts.begin() ≤ last_bft_in_test_period ≤ Bfts.end()

and we need at least one of these inequalities to be strict and I would
assert that this is true.

GC> Maybe it's just the aftereffects of yesterday's surgery, but somehow
GC> it troubles me to think that we have different empty sets that have
GC> different minimums: if a≠b, then min [a,a) ≠ min [b,b) .

 I don't think it's correct to say that these sets have different minimums.
min_element() returns different iterators for them, but neither of these
iterators can be dereferenced, so the actual value of the minimum is the
same for both empty sets: undefined/undetermined/none.

GC> I guess the explanation is that viewing C++ iterator ranges as
GC> half-open is not rigorous, when I had assumed it was.

 I do believe it is and std::min_element() seems perfectly consistent with
the usual C++ convention to me.

 Sorry if I'm still missing something here, but I just don't see what is
the problem in all this?

VZ

Attachment: pgpyWvjf5D2iE.pgp
Description: PGP signature


reply via email to

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