cppfront icon indicating copy to clipboard operation
cppfront copied to clipboard

[BUG] Initialization vs assignment in a loop

Open ntrel opened this issue 4 months ago • 2 comments

To Reproduce

main: () =
{
    i := 0;
    p: std::unique_ptr<int>;
    while i < 3 next i++ {
        std::cout << i << "\n";
        p = new<int>(i);
        std::cout << p* << "\n";
    }
}

The p = new<int> line generates a call to p.construct, which works for the first iteration to initialize p. Then on the second iteration, an assignment was intended, but p.construct is called again, which causes a contract violation.

0
0
1
Contract violation
terminate called without an active exception
Aborted (core dumped)

git cppfront, g++ (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0

ntrel avatar Apr 02 '24 17:04 ntrel

This should be rejected, just like https://cpp2.godbolt.org/z/8ssxKs4YT is:

main: () = {
  p: std::unique_ptr<int>;
  if true {
    p = new<int>(i);
  }
}
main.cpp2...
main.cpp2(2,3): error: local variable p must be initialized on both branches or neither branch
main.cpp2(3,3): error: "if" initializes p on:
  branch starting at line 3
but not on:
  implicit else branch
  ==> program violates initialization safety guarantee - see previous errors

JohelEGP avatar Apr 03 '24 21:04 JohelEGP

This should be rejected

For consistency, yes. But in both cases it would be nice to only error if the variable is actually used after the branch. If it is only used in the branch where it is initialized, that could be allowed & would be useful e.g. when a pointer (declared in the same scope as the variable) is set to point at the variable after the variable is initialized. BTW the main readme mentions P1179, perhaps that will allow this and #440 as well.

ntrel avatar Apr 04 '24 15:04 ntrel