[solved] Release vs Debug, how to maintain the sources for both?



  • When developing a project debugging functions are allover the source code ready to give useful information during tests. But then, when all testing is over, you need to release your application without any debugging functions you've been using, without any debugging symbols ect.
    Now, my question is, how do you maintain the same sources for both versions? I mean, if my code is full of debugging functions and symbols, is there any automatic way to remove them when I build in release mode?

    A good way I was always using in my sources was using a preprocessor directive ( #ifdef DEBUG MyDebugFCall() #endif ) for every debugging line used in my source code, but this is very nasty... I'm tired of writing it every time. I am looking for way to simply use the debugging function call (or anything I use for debug) and then, somehow, when I compile in release mode these lines of code would get ignored.

    Do you have a better way to do this?



  • [quote]I am looking for way to simply use the debugging function call (or anything I use for debug) and then, somehow, when I compile in release mode these lines of code would get ignored.[/quote]

    The C pre-processor is definitely the way to go here!

    Removing the Debug code completely is a very bad idea, since in any real software you will have to do debugging again - sooner or later ;-)

    If you don't want to write like this everywhere:
    @#ifdef DEBUG
    MyDebugFCall(42);
    #endif@

    Why not simply do something like this once at the top of the source file (or in some header file that you include in all your source files):
    @#ifdef DEBUG
    void __MyDebugFCall(X);
    #define MyDebugFCall(X) __MyDebugFCall(X)
    #else
    #define MyDebugFCall(X) (0)
    #endif@

    Note that __MyDebugFCall() is the actual debug function that is implemented in a separate ".cpp" file that you only compile+link in DEBUG builds.

    __

    Then in the code you can simply write stuff like:
    @SomeRegularFunction(123);
    MyDebugFCall(42);
    SomeRegularFunction(123);@

    In Debug mode this would compile to:
    @SomeRegularFunction(123);
    __MyDebugFCall(42);
    SomeRegularFunction(123);@

    ...while in a RELEASE build it would compile to:
    @SomeRegularFunction(123);
    (0); //Note that the compiler effectively kills this line completely!
    SomeRegularFunction(123);@



  • You mean that a line like (0); would be totally ignored by the compiler, like even skipping compiling it ?



  • Yes! It does not perform any calculations nor does it have any side-effects. So what assembly code should the compiler generate for that?

    You could even write a line like "int jXjbEidChl7l = 42;" and the compiler would almost certainly optimize that line out, because the value is never read.

    Also it's very common to #define functions as (0) in order to "disable" them.


  • Moderators

    or even define them as "nothing" to safe the compiler an extra step of optimization ;)
    @
    #ifdef DEBUG
    void __MyDebugFCall(X);
    #define MyDebugFCall(X) __MyDebugFCall(X)
    #else
    #define MyDebugFCall(X)
    #endif
    @



  • [quote author="raven-worx" date="1384155249"]or even define them as "nothing" to safe the compiler an extra step of optimization ;)[/quote]

    I don't think this is a good idea, because now you are going to get "orphaned" semicolon ; characters in your source code in RELEASE mode.

    For a somewhat similar reason we usually don't define macro "functions" (multi-statement macros) like this:
    @#define someFunc(X) { .... }@

    But as:
    @#define someFunc(X) do { .... } while(0)@

    So we can safely write the following without getting an additional/superfluous semicolon after they curly braces:
    @SomeFunc(42);@

    See also:
    http://stackoverflow.com/questions/257418/do-while-0-what-is-it-good-for



  • I also would say that the preprocessor is the tool of choice.

    However if you use qDebug you can also set the definition -DQT_NO_DEBUG_OUTPUT which is of course also a preprocessor thing, but the Qt guys did the work for you in that case. ;)



  • I am using qDebug to output most things, but sometimes I actually create another QWidget window where I output things because I find it more convenient than the QtCreator panel.
    So I understand that if I compile in release the qDebug function will be voided from Qt already.
    The preprocessor macro definition seems like the best way for doing this, so I'll be using it from now on instead of the inline #ifdef. It will definitely save me time and ease my goals :)

    Thank you all very much guys!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.