Search code examples
chained-assignment

How much chained assignment possible in java?


For example

int a,b,c,d,e,f,g,h,.........................;
a=b=c=d=e=f=g=h=.............................=1;

so, how long it can be possible in java....


Solution

  • Well, let's try it out!

    codegen.sh:

    #!/bin/bash
    # indentation deliberately weird, 
    # so that the generated code is legible
    N="$1"
    echo "public class Chain$N {"
    echo "    public static void main(String[] args) {"
    for i in $(seq 1 $N)
    do
    echo "        int x$i;"
    done
    echo -n "        "
    for i in $(seq 1 $N)
    do
    echo -n "x$i="
    done
    echo "42;"
    echo "    }"
    echo "}"
    

    WARNING: don't run it in your directory with all the *.java answers for StackOverflow!!!

    test.sh:

    #!/bin/bash
    rm Chain*.java    # WARNING! DON'T RUN IT IN NON-EMPTY DIRECTORIES!
    rm Chain*.class
    for n in 10 100 1000 2000 2025 2037 2050 2075 2100
    do
      ./codegen.sh $n >> "Chain$n.java"
      (javac -Xmx1000M Chain$n.java 2> /dev/null) || echo "failed for $n"
      (java Chain$n 2> /dev/null) || echo "failed to run for $n"
    done
    

    Example Chain10.java:

    public class Chain10 {
        public static void main(String[] args) {
            int x1;
            int x2;
            int x3;
            int x4;
            int x5;
            int x6;
            int x7;
            int x8;
            int x9;
            int x10;
            x1=x2=x3=x4=x5=x6=x7=x8=x9=x10=42;
        }
    }
    

    By simple manual bisection, it's easy to find the point where it fails. On my setup, it fails for N=2075 with the default settings. The compiler crashes with the following message:

    The system is out of resources.
    Consult the following stack trace for details.
    java.lang.StackOverflowError
            at com.sun.tools.javac.comp.Check.checkType(Check.java:533)
            at com.sun.tools.javac.comp.Attr$ResultInfo.check(Attr.java:482)
            at com.sun.tools.javac.comp.Attr.check(Attr.java:281)
            at com.sun.tools.javac.comp.Attr.checkIdInternal(Attr.java:3642)
            at com.sun.tools.javac.comp.Attr.checkId(Attr.java:3490)
            at com.sun.tools.javac.comp.Attr.visitIdent(Attr.java:3233)
            at com.sun.tools.javac.tree.JCTree$JCIdent.accept(JCTree.java:2011)
            at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:576)
            at com.sun.tools.javac.comp.Attr.visitAssign(Attr.java:2994)
            at com.sun.tools.javac.tree.JCTree$JCAssign.accept(JCTree.java:1686)
            at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:576)
            at com.sun.tools.javac.comp.Attr.attribExpr(Attr.java:618)
            at com.sun.tools.javac.comp.Attr.visitAssign(Attr.java:2996)
            at com.sun.tools.javac.tree.JCTree$JCAssign.accept(JCTree.java:1686)
    

    I think that you can easily correct this by increasing the size of the stack for javac.