1

I have written a code to rotate an array of integers cyclically. For e.g. Given array - 1 2 3 4 5 6 7 8 Output array- 8 1 2 3 4 5 6 7

The problem what i am facing is, if i use auto keyword in some point then it gives weird result what is beyond my understanding. Would anyone please help me in summarizing the problem ?

#include<iostream>
#include<bits/stdc++.h>
#include <typeinfo>
using namespace std;

void rotate_one_by_one(array<int, 8> &arr)
{
    auto temp = arr[arr.size() - 1];
    //auto i = arr.size() - 2; // Output : 1 2 3 4 5 6 7 8 
    int i = arr.size() - 2;    // Output : 8 1 2 3 4 5 6 7

    for(; i > -1; --i)
    {
        arr[i+1] = arr[i];
    }
    arr.at(i+1) = temp;
}

void cyc_rotate(array<int, 8> &arr)
{
    rotate_one_by_one(arr);

    cout<<"After cyclic rotate\n";
    for(auto n : arr)
        cout<<n<<" ";
}

int main()
{
    array<int, 8> arr = {1,2,3,4,5,6,7,8};

    cyc_rotate(arr);
    return 0;
}

Please find the commented line in the code where i have mentioned the output for using auto and int type. If anyone still not able to get what i am trying to convey then please let me know.

chinmaya
  • 81
  • 8
  • 3
    Unrelated to your problem, but please read [Why should I not #include ?](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h) – Some programmer dude Jun 12 '19 at 10:54
  • Just a quick guess, but `auto` probably infers that the result is unsigned, unlike `int`. – rjg Jun 12 '19 at 10:55
  • 1
    auto will default `i` to `std::size_t` but you defined `i` as an `int`, which is a signed number. – Neijwiert Jun 12 '19 at 10:55
  • 4
    `arr.size()` is an unsigned integer. `arr.size() - 2` is unsigned. `i > -1` is equivalent to `i > 4294967295` which is always false. So the array doesn't change. – L. F. Jun 12 '19 at 10:55
  • 1
    Also, [why is `using namespace std;` considered bad practice?](https://stackoverflow.com/q/1452721/9716597) – L. F. Jun 12 '19 at 10:57
  • 3
    Turn on [compiler warnings](https://gcc.godbolt.org/z/dGp3nD) – Ayxan Haqverdili Jun 12 '19 at 11:07

2 Answers2

4

The return value of arr.size() function has unsigned type std::size_t. If variable is auto i, it becomes std::size_t type too. As it is unsigned, it can never reach a value below 0.

for(; i > -1; --i)

-1 is converted here to an unsigned value, most probably to std::numeric_limits<size_t>::max() or SIZE_MAX. As, in such case, i will never be greater then this value, the loop will never enter.

KamilCuk
  • 69,546
  • 5
  • 27
  • 60
3

auto i = arr.size() - 2 makes i a variable of type std::size_t which is an unsigned integer. It can never be negative. The comparison with -1 promotes -1 to size_t by adding std::numeric_limits<std::size_t>::max() + 1 to it. Your i can't ever be greater than that so the loop will never be entered.

You could rescue your condition with for(; i != static_cast<decltype(i)>(-1); --i) or better, use std::rotate:

#include <algorithm> // std::rotate
#include <array>
#include <iostream>

int main() {
    std::array<int, 8> arr = {1, 2, 3, 4, 5, 6, 7, 8};

    std::rotate(arr.begin(), std::prev(arr.end()), arr.end());

    for(auto i : arr) std::cout << i << " ";
    std::cout << "\n";
}

Do not use the header <bits/stdc++.h>. It's non-standard and you'll never know if you get what you need, but you will for sure include much else that you don't need.

Ted Lyngmo
  • 37,764
  • 5
  • 23
  • 50