Question

I ran into this problem when I was doing the following code:

int average = std::accumulate(vi.begin(), vi.end(), 0) / vi.size();

Without an int cast on vi.size() the output is garbage, because size() returns an unsigned integer.

I never would've figured this out if I hadn't googled a reference for vector. Is there a way of avoiding this trap? With -Wall and -pedantic, gcc doesn't seem to give any warnings about this kind of division.

Was it helpful?

Solution

gcc has the -Wconversion flag, which for this case warns me:

warning: conversion to ‘int’ from ‘std::vector<int>::size_type {aka long unsigned int}’   may alter its value [-Wconversion]
     int average = std::accumulate(vi.begin(), vi.end(), 0) / vi.size();
                                                            ^

The gcc docs says:

-Wconversion

Warn for implicit conversions that may alter a value. This includes conversions between real and integer, like abs (x) when x is double; conversions between signed and unsigned, like unsigned ui = -1; and conversions to smaller types, like sqrtf (M_PI). Do not warn for explicit casts like abs ((int) x) and ui = (unsigned) -1, or if the value is not changed by the conversion like in abs (2.0). Warnings about conversions between signed and unsigned integers can be disabled by using -Wno-sign-conversion.

For C++, also warn for confusing overload resolution for user-defined conversions; and conversions that never use a type conversion operator: conversions to void, the same type, a base class or a reference to them. Warnings about conversions between signed and unsigned integers are disabled by default in C++ unless -Wsign-conversion is explicitly enabled.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top