简体   繁体   中英

Is there an automatic way to remove debugging methods for a release build?

Note: This is an extension of an earlier question I asked here: Do additional function/method definitions increase a program's memory footprint?

When I write a class, I usually end up writing several testing/debugging methods, used to make sure the class works as it should, or for printing data to help with debugging, or for unit testing, etc. Is there an easy/automatic way to make a release without these methods, or do I need to manually delete the extra code any time I want to compile a release version?

I ask this question both from a C++ and a Java perspective. I'm using Code::Blocks and Eclipse as IDEs, if that plays into the answer somehow.

For C++ you can use preprocessor macros:

#ifnef NDEBUG
void dbgFunction() { ... }
#endif

NDEBUG is a standard macro used by assert : your assert ions won't be evaluated if NDEBUG is set.


Another idea could be that of stripping the binary (thus without touching the source code) from symbols you're not using (or from the symbols you explicitly want to remove).

From a Java perspective, there are a variety of strategies:

  • If it is snippets of code that produce log messages, use log4j or one of the other logging frameworks.

  • If it is a complete method that is unused in the production code, leave it there. At runtime, the JIT compiler will notice that it isn't used and not bother to compile it. The code may still be there at runtime (as uncompiled bytecodes), but the impact on the memory footprint will be insignificant ... given that the JVM needs a few megabytes of heap space just to get started.

  • If it is a class or collection of classes (eg JUnit test classes), put it/them in a parallel package with "test" somewhere in the package name, and filter it/them out when you create the JAR file.

  • If you are using Maven, put test classes in the "src/test/java" directory rather than "src/main/java", and the maven command will automatically exclude them.

Some developers recommend using a sourcecode preprocessor with Java, but most would say that this is a bad idea; ie it introduces more problems than it solves. For a start, the mainstream Java IDEs and debuggers don't understand proprocessor directives, so you are going to run into various tool-related issues. Besides, it is not the "Java way".

To add to peoro's answer in C++ your release projects should always have NDEBUG defined and your debug projects should always have _DEBUG defined so you can test for either of those or create your own pre-processor directives to exclude code.

I personally find it very beneficial to have a few of my own preprocessor directives from time to time and great place to put them is in stdafx.h if you are using pre-compiled header files. You can enable of disable whole features or portions of code which may be works in progress or simple undesirable for certain builds. For example in one application by modifying a single define I can switch from OpenGl to DirectX or completely exclude 3d rendering from the project.

In addition you can create new configurations for projects beyond just debug and release which have certain sets of defines and for inclusions or exclusions etc. You may want two debug versions for example one that includes the debug traces and one that has verbose logging that prints out nearly the entire stack during execution.

Use preprocessor switches

#ifdef MY_DEBUG_SWITCH
// debug code goes here
#endif

In the Java world you can use log4j for all your logging purposes, having your debug logging in your code as log.debug() . In your Production code you could run the code with the log4j property level anywhere higher than DEBUG for instance INFO . You can have more details here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM