From 30be911e1ff7912b75e10119983ae10c86bb89d8 Mon Sep 17 00:00:00 2001
From: Stephan Lachnit <stephanlachnit@debian.org>
Date: Thu, 23 Feb 2023 12:47:19 +0100
Subject: [PATCH] log: ensure __LINE__ is evaluated in log var

See https://gitlab.cern.ch/allpix-squared/allpix-squared/-/merge_requests/954 for details.

Signed-off-by: Stephan Lachnit <stephanlachnit@debian.org>
---
 src/core/utils/log.h | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/src/core/utils/log.h b/src/core/utils/log.h
index 7f3590b74..cc70a85ee 100644
--- a/src/core/utils/log.h
+++ b/src/core/utils/log.h
@@ -273,13 +273,18 @@ namespace corryvreckan {
  */
 #define LOG_ONCE(level) LOG_N(level, 1)
 
+///@{
 /**
- * @brief Generator for a local variable to hold the logging count of a message
- * @param  Count Number of allowed counts
- * @return       Local counter variable
+ * @brief Macros to generate and retrieve line-specific local variables to hold the logging count of a message
+ *
+ * Note: the double concat macro is needed to ensure __LINE__ is evaluated, see https://stackoverflow.com/a/19666216/17555746
  */
-#define GENERATE_LOG_VAR(Count) static std::atomic<int> local___FUNCTION__##Count##__LINE__(Count)
-#define GET_LOG_VARIABLE(Count) local___FUNCTION__##Count##__LINE__
+#define CONCAT_IMPL(x, y) x##y
+#define CONCAT(x, y) CONCAT_IMPL(x, y)
+#define GENERATE_LOG_VAR(Count)                                                                                             \
+    static std::atomic<int> CONCAT(local___FUNCTION__, __LINE__) { Count }
+#define GET_LOG_VARIABLE() CONCAT(local___FUNCTION__, __LINE__)
+///@}
 
 /**
  * @brief Create a logging stream if the reporting level is high enough and this message has not yet been logged more than
@@ -289,12 +294,12 @@ namespace corryvreckan {
  */
 #define LOG_N(level, max_log_count)                                                                                         \
     GENERATE_LOG_VAR(max_log_count);                                                                                        \
-    if(GET_LOG_VARIABLE(max_log_count) > 0)                                                                                 \
+    if(GET_LOG_VARIABLE() > 0)                                                                                              \
         if(corryvreckan::LogLevel::level <= corryvreckan::Log::getReportingLevel() &&                                       \
            !corryvreckan::Log::getStreams().empty())                                                                        \
     corryvreckan::Log().getStream(                                                                                          \
         corryvreckan::LogLevel::level, __FILE_NAME__, std::string(static_cast<const char*>(__func__)), __LINE__)            \
-        << std::string(--GET_LOG_VARIABLE(max_log_count) == 0 ? "[further messages suppressed] " : "")
+        << ((--GET_LOG_VARIABLE() == 0) ? "[further messages suppressed] " : "")
 
     /**
      * @brief Suppress a stream from writing any output
-- 
GitLab