Search code examples
javaperformanceassert

Compiling without assertions


I know assertions can be enabled/disabled at runtime for debugging and production, respectively. However I found that assertions also increase the size of the generated binary (about 100-200 bytes in the example below).

In C and C++, we can do this at compile time by having #define NDEBUG before #include <assert.h>.

Is there any way for the Java compiler to automatically do this? I'd like to leave them in the source code for debugging purposes later on. But I also don't want the resultant binary to be any larger than necessary (we have a size limit as design requirement).

C code:

//#define NDEBUG
#include <assert.h>

int main(void) {
    assert(0); // +200 bytes without NDEBUG, 0 with NDEBUG
    return 0;
}

Java code:

public class Test {
    public static void main(String[] args) {
        assert(System.nanoTime()==0); // increases binary size by about 200 bytes
    }
}

In response to bn.'s answer:

public class Test2 {
    public static final boolean assertions = false;

    public static void main(String[] args) {
        if(assertions) {
            assert(System.nanoTime()==0);
        }
    }
}

EDIT: In fact, it seems to me that this enabling/disabling is a more useful compile-time feature than run-time. I mean, how many end users will enable them? As far as a programmer is concerned during the debug process, he/she will likely be recompiling code anyways.


Solution

  • Personally I would not do the following because of the complexity added to the source code but javac generated the exact same intermediate code for main in the following two fragments:

    conditional asserts

    class C {
        public final static boolean assertions = false;
    
        public static void main(String[] args) {
            if(assertions) {
                assert(System.nanoTime()==0);
            }
        }
    }
    

    no asserts

    class C {
        public static void main(String[] args) {
        }
    }
    

    compiled code

      public static void main(java.lang.String[]);
        Code:
           0: return        
        LineNumberTable:
          line 3: 0
    

    EDIT

    In fact, it seems to me that this enabling/disabling is a more useful compile-time feature than run-time. I mean, how many end users will enable them?

    Its not end users that enable them, it is the customer support that tells the end user to enable them. I do wish though they were enabled, not disabled, by default.