admin管理员组

文章数量:1128993

I was digging into code of flatbuffers and it does seem to me that there is undefined behavior in the core library. But I just can't believe it is there (and it seems to work in some usecases)...

I'd highly appreciate if somebody verifies my way of thinking/shows me that I missed something :)

.h#L80

  difference_type operator-(const VectorIterator &other) const {
    return (data_ - other.data_) / element_stride;
  }

My rationale, why I think it is UB:

difference_type == std::ptrdiff_t which is based on standard Signed ["something" >= 16b] ()

Let's expect that the first parenthesis end up negative (which should be valid usecase)

  1. Now when I assume the ptrdiff_t is <= size_t:

    • We get to:

      • ptrdiff_t retval = (uint8_t* - uint8_t*)/size_t
    • pointer arithmetics also end up as ptrdiff_t. So we are at:

      • ptrdiff_t retval = ptrdiff_t/size_t
    • This leads me to:

      • Signed = Signed/Unsigned
    • And based on standard (8/11.5.3) we get the first operand of divison promoted to Unsigned: The standard snippet

      • the result will end up as "something positive and huge" as the negative number got promoted to huge unsigned one
  2. Now lets assume ptrdiff_t is > size_t

    • pretty much same steps apply, except the last one:
      • based on standard (8/11.5.4), the second operand of division get promoted to signed number of bigger bitsize
      • this leads to return value to be (the intuitive) negative number that says distance between the two VectorIterators.

So I see there 2 possible outcomes of the operator-, both complying with the standard requirements, based on ptrdiff_t implementation by specific compiler.

Thanks!

本文标签: cFlatbuffers VectorIteratoroperator undefined behaviorStack Overflow