Variadic logger dispatcher
<p>I am implementing sort of a logging dispatcher, i.e. <code>int32_t logf(const char *fmt, ...);</code> which outputs to different logging targets, depending on which options it was compiled with.</p>

<p>The following is a boiled down excerpt.</p>

<pre><code>int32_t logf(const char *fmt, ...)
{
    va_list    va;
    i32        res;

    va_start(va, fmt);

    res = S_PASS;

#ifdef LOG_UART
    res = Uart_vprintf(fmt, va);
    if (res != S_PASS) goto exit;
#endif /* LOG_UART */

#ifdef LOG_SYS
    res = System_vprintf(fmt, va);
    if (res != S_PASS) goto exit;
#endif /* LOG_SYS */

exit:
    va_end(va);

    return res;
}
</code></pre>

<p>Now... If no options are given, the logger would (and actually is intended to) be a null-logger. However, do I then still need the calls to <code>va_start()</code> and <code>va_end()</code> in there?</p>

<p>In other words (ignoring -Wunused-label for a second), is this correct:</p>

<pre><code>int32_t logf(const char *fmt, ...)
{
    va_list    va;
    i32        res;

    va_start(va, fmt);

    res = S_PASS;

exit:
    va_end(va);

    return res;
}
</code></pre>

<p>...or this?</p>

<pre><code>int32_t logf(const char *fmt, ...)
{
    i32        res;

    res = S_PASS;

    return res;
}
</code></pre>

<p><strong>UPDATE</strong></p>

<p>The resulting <em>empty</em> function implementation cannot be replaced by a function-style macro like <code>#define logf(fmt, ...) S_PASS;</code>.</p>

<p>The existing code base has defined <code>typedef int32_t(*logFunc)(const char *fmt, ...);</code> and therefore pointers to logf must be storable. </p>