Alex
Alex

Reputation: 1177

Auto failed for vector size

I am trying use auto to infer the type.

for (auto i = remaining_group.size() - 1; i >= 0; --i) {
    std::cout << i;
}

I get very large number like 18446744073709534800 which is not expected. When I change auto to int it is the number I expected between 0 and 39.

Is there any reason auto will fail here?

remaining_group's type is a std::vector<lidar_point> and lidar_point is struct like:

struct LidarPoint {
  float x;
  float y;
  float z;
  uint8_t field1;
  double field2;
  uint8_t field3;
  uint16_t field4;
}

Upvotes: 2

Views: 394

Answers (3)

tnt
tnt

Reputation: 1184

If you need a reverse index loop, use operator -->

When you write a normal index loop, you write it with 0, size, and <.

When you write a normal reverse index loop, things become a bit wonky: you need size - 1, >=, 0, and you can't use unsigned index, because unsigned i is always >= 0 so your check i >= 0 always returns true, your loop could run forever.

With fake operator "goes to", you can use 0, size, and > to write the reverse index loop, and it doesn't matter if i is signed or unsigned:

for (auto i = a.size(); i --> 0; ) //or just i--, or i --> 1, i --> 10...
    std::cout << i << ' ';

Upvotes: 1

Swift - Friday Pie
Swift - Friday Pie

Reputation: 14589

Simple reproduction of problem:

#include <iostream>

size_t size()  {return 1;}

int main() {
   for (auto i = size() - 1; i >= 0; --i) {
    std::cout << i << std::endl;
   }
}

size() got type size_t and literal constant 1 would be promoted to size_t, in result auto would become size_t, which cannot be less than zero, resulting in infinite loop and underflow of i.

Upvotes: 1

songyuanyao
songyuanyao

Reputation: 172924

When using auto the type of i would be std::vector::size_type, which is an unsigned integer type. That means the condition i >= 0; would be always true, and if overflow happens you'll get some large numbers.

Unsigned integer arithmetic is always performed modulo 2n where n is the number of bits in that particular integer. E.g. for unsigned int, adding one to UINT_MAX gives ​0​, and subtracting one from ​0​ gives UINT_MAX.

Upvotes: 2

Related Questions