TEnumerableBase<T>.Sum doesn't handle Bytes and Words correctly

Issue #369 resolved
Patrick Anke created an issue

If you create an IList<Byte> and call Sum on it, you may get an access violation when optimizations are switched on. This is because of the cast to PInteger, although the value is only 1 or 2 bytes long. Might be the same problem for other data types.

Comments (5)

  1. Stefan Glienke repo owner

    This is an admittedly ugly limitation currently - given that Sum returns the type of the sequence itself when using small data types the usefulness of Sum with that signature is questionable as it will very likely overflow anyway.

    In .NET this is being solved by providing this method via extension methods only for IEnumerable of int, long, single and double but provide one where you pass a selector to turn your type T into int, long, single or double. (see the uncommented code below the Sum declaration in Spring.Collections). I did not find a satisfying implementation for this to not pollute the binary code with several overloads.

    In the meanwhile I suggest you write the code like this:

    TEnumerable.Select<Byte,Integer>(list,function(const x: Byte): Integer begin Result := x; end).Sum;
    

    I will consider putting a check into the method though that prevents getting bad data or an AV.

  2. Patrick Anke Account Deactivated reporter

    I’ve changed my List already to a List of Integer, so the problem is in control in our code base. But yes, i get what you are saying. The return type is the real problem here, to make it useful at least. As another note: you also get a problem with a List of Cardinals, if one of them is bigger than Integer.MaxValue.

  3. Log in to comment