Print-based debugging
Although it's a short function/macro, there are a number of problems here:

__FILE__ and __LINE__ are expanded in the function definition, rather than at the call site.  We need an interface that passes those in, so that the macro is
  #define debug(args...) if (DEBUG) _debug(__FILE__, __LINE__, args);


That's a non-standard variadic macro expansion.  The standard way is to write the parameter as ... and expand it using __VA_ARGS__.

Identifiers in global scope beginning with underscore are reserved for the implementation.  Use a namespace instead (e.g. debugging::debug).

Debug information should go to std::clog, not std::cout.

The macro doesn't play nicely in if/else statements - use the do...while(0) idiom to make it statement-like.

Conventional style is to use all-caps for macros (to indicate their dangers) and nothing else.  We have this exactly backwards here, with debug and DEBUG.



Improved version
#include &lt;iostream&gt;

namespace debugging
{
#ifdef ENABLE_DEBUG
    constexpr bool debug = true;
#else
    constexpr bool debug = false;
#endif

    template &lt;typename... Args&gt;
    void print(const char* file, int line, Args... args) {
        (std::clog &lt;&lt; &quot;[&quot; &lt;&lt; file &lt;&lt; &quot;:&quot; &lt;&lt; line &lt;&lt; &quot;] &quot;
                  &lt;&lt; ... &lt;&lt; args) &lt;&lt; std::endl;
    }
}

#define DEBUG(...)                                              \
    do {                                                        \
        if (debugging::debug)                                   \
            debugging::print(__FILE__, __LINE__, __VA_ARGS__);  \
    } while (0)

And a quick test (that demonstrates that the arguments are evaluated only when we're debugging):
int main()
{
    DEBUG(&quot;Started main&quot;);
    int status = 1;
    DEBUG(&quot;Leaving main, status=&quot;, status=0);
    return status;
}


Addendum
We don't need the debug constant - just change the definition of the macro according to whether or not we're debugging:
#ifndef ENABLE_DEBUG
#define DEBUG(...)  ((void)0)
#else
#include &lt;iostream&gt;

namespace debugging
{
    template&lt;typename... Args&gt;
    void print(const char* file, int line, Args... args) {
        (std::clog &lt;&lt; &quot;[&quot; &lt;&lt; file &lt;&lt; &quot;:&quot; &lt;&lt; line &lt;&lt; &quot;] &quot;
                  &lt;&lt; ... &lt;&lt; args) &lt;&lt; std::endl;
    }
}

#define DEBUG(...)  debugging::print(__FILE__, __LINE__, __VA_ARGS__)
#endif