Reputation: 53
I have a bug in a program of mine which I find very confusing.
Below is a minimal version of the problematic code to reproduce my bug.
#include <iostream>
struct derp
{
int idx;
};
int main (int argc, char **argv)
{
derp initial;
initial.idx = 0;
derp *prev = &initial;
while (true)
{
int c;
while ((c = getchar()) != '\n' && c != EOF)
{
}
if (c == EOF)
{
break;
}
derp cur;
cur.idx = prev->idx + 1;
std::cerr << "Prev: " << prev->idx << ", cur: " << cur.idx << std::endl;
prev = &cur;
}
}
Save it as wtf.cpp
.
Compile.
$ CC wtf.cpp
Run.
$ (echo;echo;echo) | ./a.out
Expected output:
Prev: 0, cur: 1
Prev: 1, cur: 2
Prev: 2, cur: 3
Actual output when running:
Prev: 0, cur: 1
Prev: 2, cur: 2
Prev: 3, cur: 3
I am using CC from Oracle Solaris Studio 12.4 on Sun Solaris 10 10/09 s10x_u8wos_08a X86.
Upvotes: 2
Views: 1502
Reputation: 726809
The problem is that your code uses an out-of-scope pointer. Any reference to cur
that was valid in a prior iteration of the loop is invalid as soon as you get to the next iteration. That's why the first iteration, when prev
points to initial
, is the only iteration when your code works as expected. On subsequent iterations prev
happens to point to the same place as cur
, because the compiler keeps it in the same place in all iterations of the loop. However, the behavior is undefined, so you may get different results when compiling with other compilers.
You need to declare both prev
and cur
outside the loop, and make a copy of the entire structure, like this:
derp prev;
prev.idx = 0;
derp cur;
while (true) {
int c;
while ((c = getchar()) != '\n' && c != EOF)
{
}
if (c == EOF)
{
break;
}
cur.idx = prev.idx + 1;
std::cerr << "Prev: " << prev.idx << ", cur: " << cur.idx << std::endl;
prev = cur;
}
Upvotes: 3
Reputation: 1322
prev is a pointer, and it initially points to a variable that retains its scope throughout the while loop. Then in the while loop, you create a new variable 'cur', which has a scope limited to that iteration, and save a pointer to that temporary variable. Try defining cur outside the while loop.
Cheers!
Upvotes: 2