'Naive reverse string iteration infinite loop and/or assertion failure C++ / Visual Studio 2022
I am trying to reverse iterate through a string, but am getting assertion failure for the [] operator in the latest VS.
int foo() {
std::string s = "s";
for (int i = (s.size() - 1); i >= 0; i--) {
std::cout << s[i] << std::endl;
}
return 0;
}
Commenting out the cout line gives infinite loop warning and indeed enters infinite loop:
int foo2() {
std::string s = "s";
for (int i = (s.size() - 1); i >= 0; i--) {
//std::cout << s[i] << std::endl;
}
return 0;
}
Iterating forwards works just fine with or without anything in the for loop:
int bar() {
std::string s = "s";
for (int i = 0; i < s.size(); i++) {
std::cout << s[i] << std::endl;
}
return 0;
}
I am using the C++14 standard and the same code used to work on other compilers/older versions of VS. The same problem exists for any string size (although that should be irrelevant). I understand I could modify the code to use and dereference pointer instead of using int, but want to understand why this doesn't work anymore, why is it unsafe or incorrect, or what else am I missing. Thanks!
Solution 1:[1]
Could it be that your int defaults to being unsigned and therefore decrementing when i=0 resuts in a high value ?
As @PeteBecker mentioned, int should be signed and should not overflow. However my guess is that your actual code does not use int.
Solution 2:[2]
Commenting out the cout line gives infinite loop warning and indeed enters infinite loop
s.size()
is an unsigned long
so it can never be less than 0
. The behavior of narrowing conversion due to assignment of unsigned long
to int
is implementation defined behavior though it should not be a problem when assigning unsigned long
value 0 to int
, at least I wouldn't think so, but who knows, MSVC does have its quirks.
It appears the compiler is smart enough to predict that there cannot be an infinite loop when this particular body of the for
loop is present, which leads me to believe that an exception may be thrown when accessing the array, perhaps out of bounds access.
Using the debugger to track the value of i
is your best bet to understand what is going on.
Solution 3:[3]
The issue was in fact originally caused by "auto" i rather than "int" i, but not properly refreshed. Auto gave i an unsigned int type, which overflowed the [] operator, or caused infinite loop turning over from zero to 18446744073709551615 once the i = 0 cycle completes and i-- is executed.
Thank you everyone for the helpful replies!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | |
Solution 3 | Z_C |