Is leaving debug sections in the source code a good practise?

Is leaving debug sections in the source code a good practise?

#ifndef NODEBUG
    trace("Function End %s", __FUNCTION__);

There is no hard and fast rule of whether debug code should be removed. Sometime it's a common sense and up to the person who writes the code to decide.

Clearly for your example, it's trivial enough to delete those debug code out for readability.

However, some/many debug code is not trivial. It takes time to write. And some time it's very important for a developer to re-enable those code to track and debug some real problem when it happens. In those cases, it's clearly very useful to keep those debug code in for later usage/debugging.

It's not generally a bad practice to add code within debug sections. As long as this code doesn't fundamentally change the behavior of your function, it doesn't add much complexity and can give you useful information. However, it does decrease readability.

It is very rare that you really need a dedicated code section that only runs on debug builds. What I very commonly do myself instead is create specialized macros that only perform an action on debug builds. This ends up being much more concise and readable. For example:

// defined in some utility header
#ifndef NODEBUG
#define DEBUG_TRACE(...) trace(__VA_ARGS__)
#define DEBUG_TRACE(...)

void do_something() {
    int var = 10

    DEBUG_TRACE("Function Start %s", __FUNCTION__);

    while (someCondition) {
        var += 1
        DEBUG_TRACE("Var = %d \n", var);
    // ... (Do some other stuff)
    // ... (Do some more stuff)

    DEBUG_TRACE("Function End %s", __FUNCTION__);

If you were to add a #ifndef NODEBUG code section now, it would become much more obvious that you are changing the behavior of the function instead of just logging something.

This practice can be applied not only to logging but to assertions and other things which only compile on debug builds. If you do this a lot, then the following macros can be of help too:

#ifndef NODEBUG
#define IF_DEBUG_ELSE(expr, alt) expr
#define IF_DEBUG(...) __VA_ARGS__
#define IF_DEBUG_ELSE(expr, alt) alt
#define IF_DEBUG(...)

void example(int x) {
    IF_DEBUG_ELSE(/* action on debug builds */, /* action on release builds */);
    IF_DEBUG(/* one-liner action only on debug builds */);