]> git.kaiwu.me - haproxy.git/commitdiff
MINOR: trace: always pretend to use args when disabled
authorWilly Tarreau <w@1wt.eu>
Wed, 1 Jul 2026 12:42:58 +0000 (14:42 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 3 Jul 2026 14:32:28 +0000 (16:32 +0200)
When traces are disabled, we used to make TRACE() and other macros just
emit a "do { } while (0)" statement, which has the unfortunate limitation
of explicitly marking the arguments as not used. As such, all variables
that are initialized in functions for the sole purpose of being passed
to the trace calls end up emitting warnings about "foo defined but not
used". It is difficult to keep these in a clean state all the time, and
to always think about adding __maybe_unused after each declaration, and
the traces try hard to be developer-friendly in order to gain in adoption.

Let's just remap all macros to __eat_all_args() which will mark all
arguments as used. No code is emitted, the output binary is the same
as with the while(0) stuff, but syntactically speaking the argument is
used and the compiler is happy.

It may be useful to backport this to 3.4 as it's already expected that
some future fixes will trigger build warnings there otherwise. This
commit requires these two ones:

  CLEANUP: traces: get rid of a few rare empty args in TRACE calls
  MINOR: compiler: add a macro to ignore all arguments

include/haproxy/trace.h

index 626609a377a3012bc5cd6606a128ec4657740800..bdd4059c4b9148bfad484f1f268e9d2504edd163 100644 (file)
        } while (0)
 #else
 #    define TRACE_ENABLED(level, mask, args...) 0
-#    define TRACE(msg, mask, args...)        do { /* do nothing */ } while(0)
-#    define TRACE_ERROR(msg, mask, args...)  do { /* do nothing */ } while(0)
-#    define TRACE_USER(msg, mask, args...)   do { /* do nothing */ } while(0)
-#    define TRACE_DATA(msg, mask, args...)   do { /* do nothing */ } while(0)
-#    define TRACE_PROTO(msg, mask, args...)  do { /* do nothing */ } while(0)
-#    define TRACE_STATE(msg, mask, args...)  do { /* do nothing */ } while(0)
-#    define TRACE_DEVEL(msg, mask, args...)  do { /* do nothing */ } while(0)
-#    define TRACE_ENTER(mask, args...)       do { /* do nothing */ } while(0)
-#    define TRACE_LEAVE(mask, args...)       do { /* do nothing */ } while(0)
-#    define TRACE_POINT(mask, args...)       do { /* do nothing */ } while(0)
-#    define TRACE_PRINTF(level, args...)     do { /* do nothing */ } while(0)
-#    define TRACE_PRINTF_LOC(level, args...) do { /* do nothing */ } while(0)
+#    define TRACE(msg, mask, args...)        __eat_all_args(msg, mask, ##args)
+#    define TRACE_ERROR(msg, mask, args...)  __eat_all_args(msg, mask, ##args)
+#    define TRACE_USER(msg, mask, args...)   __eat_all_args(msg, mask, ##args)
+#    define TRACE_DATA(msg, mask, args...)   __eat_all_args(msg, mask, ##args)
+#    define TRACE_PROTO(msg, mask, args...)  __eat_all_args(msg, mask, ##args)
+#    define TRACE_STATE(msg, mask, args...)  __eat_all_args(msg, mask, ##args)
+#    define TRACE_DEVEL(msg, mask, args...)  __eat_all_args(msg, mask, ##args)
+#    define TRACE_ENTER(mask, args...)       __eat_all_args(mask, ##args)
+#    define TRACE_LEAVE(mask, args...)       __eat_all_args(mask, ##args)
+#    define TRACE_POINT(mask, args...)       __eat_all_args(mask, ##args)
+#    define TRACE_PRINTF(level, args...)     __eat_all_args(level, ##args)
+#    define TRACE_PRINTF_LOC(level, args...) __eat_all_args(level, ##args)
 #endif
 
 #if defined (USE_TRACE) && (defined(DEBUG_DEV) || defined(DEBUG_FULL))
 #    define DBG_TRACE_PRINTF(level, args...)     TRACE_PRINTF(level, ##args)
 #    define DBG_TRACE_PRINTF_LOC(level, args...) TRACE_PRINTF_LOC(level, ##args)
 #else
-#    define DBG_TRACE(msg, mask, args...)        do { /* do nothing */ } while(0)
-#    define DBG_TRACE_ERROR(msg, mask, args...)  do { /* do nothing */ } while(0)
-#    define DBG_TRACE_USER(msg, mask, args...)   do { /* do nothing */ } while(0)
-#    define DBG_TRACE_DATA(msg, mask, args...)   do { /* do nothing */ } while(0)
-#    define DBG_TRACE_PROTO(msg, mask, args...)  do { /* do nothing */ } while(0)
-#    define DBG_TRACE_STATE(msg, mask, args...)  do { /* do nothing */ } while(0)
-#    define DBG_TRACE_DEVEL(msg, mask, args...)  do { /* do nothing */ } while(0)
-#    define DBG_TRACE_ENTER(mask, args...)       do { /* do nothing */ } while(0)
-#    define DBG_TRACE_LEAVE(mask, args...)       do { /* do nothing */ } while(0)
-#    define DBG_TRACE_POINT(mask, args...)       do { /* do nothing */ } while(0)
-#    define DBG_TRACE_PRINTF(level, args...)     do { /* do nothing */ } while(0)
-#    define DBG_TRACE_PRINTF_LOC(level, args...) do { /* do nothing */ } while(0)
+#    define DBG_TRACE(msg, mask, args...)        __eat_all_args(msg, mask, ##args)
+#    define DBG_TRACE_ERROR(msg, mask, args...)  __eat_all_args(msg, mask, ##args)
+#    define DBG_TRACE_USER(msg, mask, args...)   __eat_all_args(msg, mask, ##args)
+#    define DBG_TRACE_DATA(msg, mask, args...)   __eat_all_args(msg, mask, ##args)
+#    define DBG_TRACE_PROTO(msg, mask, args...)  __eat_all_args(msg, mask, ##args)
+#    define DBG_TRACE_STATE(msg, mask, args...)  __eat_all_args(msg, mask, ##args)
+#    define DBG_TRACE_DEVEL(msg, mask, args...)  __eat_all_args(msg, mask, ##args)
+#    define DBG_TRACE_ENTER(mask, args...)       __eat_all_args(mask, ##args)
+#    define DBG_TRACE_LEAVE(mask, args...)       __eat_all_args(mask, ##args)
+#    define DBG_TRACE_POINT(mask, args...)       __eat_all_args(mask, ##args)
+#    define DBG_TRACE_PRINTF(level, args...)     __eat_all_args(level, ##args)
+#    define DBG_TRACE_PRINTF_LOC(level, args...) __eat_all_args(level, ##args)
 #endif
 
 extern struct list trace_sources;