stedolan / counterexamples

Counterexamples in Type Systems
http://counterexamples.org
372 stars 23 forks source link

Proposed change to "Objects under construction" #14

Open Quelklef opened 2 years ago

Quelklef commented 2 years ago

The cast (A)x.o can be removed from this code sample by replacing the public Object o field of Ex with a public A o field. This change produces the following code:

class Ex extends RuntimeException {
    public A o;
    public Ex(A a) { this.o = a; }
    static int leak(A x) { throw new Ex(x); }
}

class A {
    public final int leak = Ex.leak(this);
    public final int thing = Integer.parseInt("42");
}

public class Test {
    static A make() {
        try {
            return new A();
        } catch (Ex x) {
            return (A)x.o;
        }
    }
    public static void main(String []args){
       A a = make();
       // a is uninitialised: its 'thing' field is zero
       System.out.println(a.thing);
    }
}

I might also suggest the following code, which makes changes for readability. This is more subjective, though, hence the separate suggestion:

class Ex extends RuntimeException {
    public A a;
    public Ex(A a) { this.a = a; }
}

class A {
    public final int x = fail(this);
    static int fail(A it) { throw new Ex(it); }

    public final int num = one();
    static int one() { return 1; }
}

public class Test {
    public static void main(String []args){
       A a;
       try {
         a = new A();
       } catch (Ex ex) {
         a = ex.a;
       }

       // a is not fully initialized: its 'num' field is zero
       System.out.println(a.num);
    }
}

Note: I went to make a PR about this, but running make failed for me. I guess my system isn't similar enough to yours ¯\_(ツ)_/¯

Anyway, love the project!