An Interesting C++ Templated Parameter Gotcha

February 23, 2014

One of many nifty algorithms included in the STL is std::accumulate() found in the numeric header. I generally use this any time I need to sum values from a start to an end.

It's a really simple function that the standard defines like so.

template< class InputIt, class T >
T accumulate( InputIt first, InputIt last, T init );

Do you see anything wrong with the following code which you've probably written any time you have used std::accumulate()?

vector<long long> values;
...
long long n = std::accumulate(values.begin(),values.end(),0);

Well, there is something very wrong with this. The problem isn't truly even a C++ problem or an std::accumulate() problem. How about the same code with some more details about what values contains?

vector<long long> values;
 
for (size_t x = 0; x < 1000000;x++)
   values.push_back(1000000);
 
long long n = std::accumulate(values.begin(),values.end(),0);
cout << n << endl;

The output of n should be 10^12 or 1000000000000. Obviously we need a 64 bit value to store this, and we've used one. However, the output of the code as written is -727379968.

If you have not figured out by now, it's the literal zero that is interpreted as the signed 32 bit type int that's supplied as the third argument to accumulate. Not only is that third argument the initial value, it's also the template parameter that std::accumulate() is using for its sum value type and return type. That is obviously not what was intended.

#include <iostream>
#include <vector>
#include <numeric>
 
int main()
{
   vector<long long> values;
 
   for (size_t x = 0; x < 1000000;x++)
      values.push_back(1000000);
 
   long long n = std::accumulate(values.begin(),values.end(),0LL);
   cout << n << endl;
 
   return 0;
}

Using the literal 0LL or equivalent fixes this issue.

I know the feeling you're having right now. You're probably already scanning all of the code you're written in your head trying to remember if you have the same problem.

Related Posts

1 Comment

Comment February 27, 2014 by anonymous
>I know the feeling you're having right now. No,you don't! I haven't found any gotchas here. I saw the problem as soon as I saw the code.