Răsfoiți Sursa

[cxx]: No ##__VA_ARGS__ in public header files

* ##__VA_ARGS__ is replaced by __VA_OPT__(,)
  and __VA_ARGS if C++20 is used.
* Affected header files are: esp_log.h,
  portmacro.h and esp_check.h

* Closes https://github.com/espressif/esp-idf/pull/6692
Jakob Hasse 4 ani în urmă
părinte
comite
f6031d469b

+ 183 - 62
components/esp_common/include/esp_check.h

@@ -30,41 +30,21 @@ extern "C" {
             return err_rc_;                                                                     \
         }                                                                                       \
     } while(0)
-#else
-#define ESP_RETURN_ON_ERROR(x, log_tag, format, ...) do {                                       \
-        esp_err_t err_rc_ = (x);                                                                \
-        if (unlikely(err_rc_ != ESP_OK)) {                                                      \
-            ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__);        \
-            return err_rc_;                                                                     \
-        }                                                                                       \
-    } while(0)
-#endif
 
 /**
  * A version of ESP_RETURN_ON_ERROR() macro that can be called from ISR.
  */
-#if defined(CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT)
 #define ESP_RETURN_ON_ERROR_ISR(x, log_tag, format, ...) do {                                   \
         esp_err_t err_rc_ = (x);                                                                \
         if (unlikely(err_rc_ != ESP_OK)) {                                                      \
             return err_rc_;                                                                     \
         }                                                                                       \
     } while(0)
-#else
-#define ESP_RETURN_ON_ERROR_ISR(x, log_tag, format, ...) do {                                   \
-        esp_err_t err_rc_ = (x);                                                                \
-        if (unlikely(err_rc_ != ESP_OK)) {                                                      \
-            ESP_EARLY_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__);  \
-            return err_rc_;                                                                     \
-        }                                                                                       \
-    } while(0)
-#endif
 
 /**
  * Macro which can be used to check the error code. If the code is not ESP_OK, it prints the message,
  * sets the local variable 'ret' to the code, and then exits by jumping to 'goto_tag'.
  */
-#if defined(CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT)
 #define ESP_GOTO_ON_ERROR(x, goto_tag, log_tag, format, ...) do {                               \
         esp_err_t err_rc_ = (x);                                                                \
         if (unlikely(err_rc_ != ESP_OK)) {                                                      \
@@ -72,29 +52,200 @@ extern "C" {
             goto goto_tag;                                                                      \
         }                                                                                       \
     } while(0)
-#else
-#define ESP_GOTO_ON_ERROR(x, goto_tag, log_tag, format, ...) do {                               \
+
+/**
+ * A version of ESP_GOTO_ON_ERROR() macro that can be called from ISR.
+ */
+#define ESP_GOTO_ON_ERROR_ISR(x, goto_tag, log_tag, format, ...) do {                           \
         esp_err_t err_rc_ = (x);                                                                \
         if (unlikely(err_rc_ != ESP_OK)) {                                                      \
-            ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__);        \
             ret = err_rc_;                                                                      \
             goto goto_tag;                                                                      \
         }                                                                                       \
     } while(0)
-#endif
+
+/**
+ * Macro which can be used to check the condition. If the condition is not 'true', it prints the message
+ * and returns with the supplied 'err_code'.
+ */
+#define ESP_RETURN_ON_FALSE(a, err_code, log_tag, format, ...) do {                             \
+        if (unlikely(!(a))) {                                                                   \
+            return err_code;                                                                    \
+        }                                                                                       \
+    } while(0)
+
+/**
+ * A version of ESP_RETURN_ON_FALSE() macro that can be called from ISR.
+ */
+#define ESP_RETURN_ON_FALSE_ISR(a, err_code, log_tag, format, ...) do {                         \
+        if (unlikely(!(a))) {                                                                   \
+            return err_code;                                                                    \
+        }                                                                                       \
+    } while(0)
+
+/**
+ * Macro which can be used to check the condition. If the condition is not 'true', it prints the message,
+ * sets the local variable 'ret' to the supplied 'err_code', and then exits by jumping to 'goto_tag'.
+ */
+#define ESP_GOTO_ON_FALSE(a, err_code, goto_tag, log_tag, format, ...) do {                     \
+        if (unlikely(!(a))) {                                                                   \
+            ret = err_code;                                                                     \
+            goto goto_tag;                                                                      \
+        }                                                                                       \
+    } while (0)
+
+/**
+ * A version of ESP_GOTO_ON_FALSE() macro that can be called from ISR.
+ */
+#define ESP_GOTO_ON_FALSE_ISR(a, err_code, goto_tag, log_tag, format, ...) do {                 \
+        if (unlikely(!(a))) {                                                                   \
+            ret = err_code;                                                                     \
+            goto goto_tag;                                                                      \
+        }                                                                                       \
+    } while (0)
+
+#else // !CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT
+
+/**
+ * In the future, we want to switch to C++20. We also want to become compatible with clang.
+ * Hence, we provide two versions of the following macros. The first one is using the GNU extension \#\#__VA_ARGS__.
+ * The second one is using the C++20 feature __VA_OPT__(,). This allows users to compile their code with
+ * standard C++20 enabled instead of the GNU extension. Below C++20, we haven't found any good alternative to
+ * using \#\#__VA_ARGS__.
+ */
+#if defined(__cplusplus) && (__cplusplus >  201703L)
+
+/**
+ * Macro which can be used to check the error code. If the code is not ESP_OK, it prints the message and returns.
+ */
+#define ESP_RETURN_ON_ERROR(x, log_tag, format, ...) do {                                                  \
+        esp_err_t err_rc_ = (x);                                                                           \
+        if (unlikely(err_rc_ != ESP_OK)) {                                                                 \
+            ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__);        \
+            return err_rc_;                                                                                \
+        }                                                                                                  \
+    } while(0)
+
+/**
+ * A version of ESP_RETURN_ON_ERROR() macro that can be called from ISR.
+ */
+#define ESP_RETURN_ON_ERROR_ISR(x, log_tag, format, ...) do {                                              \
+        esp_err_t err_rc_ = (x);                                                                           \
+        if (unlikely(err_rc_ != ESP_OK)) {                                                                 \
+            ESP_EARLY_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__);  \
+            return err_rc_;                                                                                \
+        }                                                                                                  \
+    } while(0)
+
+/**
+ * Macro which can be used to check the error code. If the code is not ESP_OK, it prints the message,
+ * sets the local variable 'ret' to the code, and then exits by jumping to 'goto_tag'.
+ */
+#define ESP_GOTO_ON_ERROR(x, goto_tag, log_tag, format, ...) do {                                          \
+        esp_err_t err_rc_ = (x);                                                                           \
+        if (unlikely(err_rc_ != ESP_OK)) {                                                                 \
+            ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__);        \
+            ret = err_rc_;                                                                                 \
+            goto goto_tag;                                                                                 \
+        }                                                                                                  \
+    } while(0)
 
 /**
  * A version of ESP_GOTO_ON_ERROR() macro that can be called from ISR.
  */
-#if defined(CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT)
-#define ESP_GOTO_ON_ERROR_ISR(x, goto_tag, log_tag, format, ...) do {                           \
+#define ESP_GOTO_ON_ERROR_ISR(x, goto_tag, log_tag, format, ...) do {                                      \
+        esp_err_t err_rc_ = (x);                                                                           \
+        if (unlikely(err_rc_ != ESP_OK)) {                                                                 \
+            ESP_EARLY_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__);  \
+            ret = err_rc_;                                                                                 \
+            goto goto_tag;                                                                                 \
+        }                                                                                                  \
+    } while(0)
+
+/**
+ * Macro which can be used to check the condition. If the condition is not 'true', it prints the message
+ * and returns with the supplied 'err_code'.
+ */
+#define ESP_RETURN_ON_FALSE(a, err_code, log_tag, format, ...) do {                                        \
+        if (unlikely(!(a))) {                                                                              \
+            ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__);        \
+            return err_code;                                                                               \
+        }                                                                                                  \
+    } while(0)
+
+/**
+ * A version of ESP_RETURN_ON_FALSE() macro that can be called from ISR.
+ */
+#define ESP_RETURN_ON_FALSE_ISR(a, err_code, log_tag, format, ...) do {                                    \
+        if (unlikely(!(a))) {                                                                              \
+            ESP_EARLY_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__);  \
+            return err_code;                                                                               \
+        }                                                                                                  \
+    } while(0)
+
+/**
+ * Macro which can be used to check the condition. If the condition is not 'true', it prints the message,
+ * sets the local variable 'ret' to the supplied 'err_code', and then exits by jumping to 'goto_tag'.
+ */
+#define ESP_GOTO_ON_FALSE(a, err_code, goto_tag, log_tag, format, ...) do {                                \
+        if (unlikely(!(a))) {                                                                              \
+            ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__);        \
+            ret = err_code;                                                                                \
+            goto goto_tag;                                                                                 \
+        }                                                                                                  \
+    } while (0)
+
+/**
+ * A version of ESP_GOTO_ON_FALSE() macro that can be called from ISR.
+ */
+#define ESP_GOTO_ON_FALSE_ISR(a, err_code, goto_tag, log_tag, format, ...) do {                            \
+        if (unlikely(!(a))) {                                                                              \
+            ESP_EARLY_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__);  \
+            ret = err_code;                                                                                \
+            goto goto_tag;                                                                                 \
+        }                                                                                                  \
+    } while (0)
+
+#else // !(defined(__cplusplus) && (__cplusplus >  201703L))
+
+/**
+ * Macro which can be used to check the error code. If the code is not ESP_OK, it prints the message and returns.
+ */
+#define ESP_RETURN_ON_ERROR(x, log_tag, format, ...) do {                                       \
+        esp_err_t err_rc_ = (x);                                                                \
+        if (unlikely(err_rc_ != ESP_OK)) {                                                      \
+            ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__);        \
+            return err_rc_;                                                                     \
+        }                                                                                       \
+    } while(0)
+
+/**
+ * A version of ESP_RETURN_ON_ERROR() macro that can be called from ISR.
+ */
+#define ESP_RETURN_ON_ERROR_ISR(x, log_tag, format, ...) do {                                   \
         esp_err_t err_rc_ = (x);                                                                \
         if (unlikely(err_rc_ != ESP_OK)) {                                                      \
+            ESP_EARLY_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__);  \
+            return err_rc_;                                                                     \
+        }                                                                                       \
+    } while(0)
+
+/**
+ * Macro which can be used to check the error code. If the code is not ESP_OK, it prints the message,
+ * sets the local variable 'ret' to the code, and then exits by jumping to 'goto_tag'.
+ */
+#define ESP_GOTO_ON_ERROR(x, goto_tag, log_tag, format, ...) do {                               \
+        esp_err_t err_rc_ = (x);                                                                \
+        if (unlikely(err_rc_ != ESP_OK)) {                                                      \
+            ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__);        \
             ret = err_rc_;                                                                      \
             goto goto_tag;                                                                      \
         }                                                                                       \
     } while(0)
-#else
+
+/**
+ * A version of ESP_GOTO_ON_ERROR() macro that can be called from ISR.
+ */
 #define ESP_GOTO_ON_ERROR_ISR(x, goto_tag, log_tag, format, ...) do {                           \
         esp_err_t err_rc_ = (x);                                                                \
         if (unlikely(err_rc_ != ESP_OK)) {                                                      \
@@ -103,57 +254,32 @@ extern "C" {
             goto goto_tag;                                                                      \
         }                                                                                       \
     } while(0)
-#endif
 
 /**
  * Macro which can be used to check the condition. If the condition is not 'true', it prints the message
  * and returns with the supplied 'err_code'.
  */
-#if defined(CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT)
-#define ESP_RETURN_ON_FALSE(a, err_code, log_tag, format, ...) do {                             \
-        if (unlikely(!(a))) {                                                                   \
-            return err_code;                                                                    \
-        }                                                                                       \
-    } while(0)
-#else
 #define ESP_RETURN_ON_FALSE(a, err_code, log_tag, format, ...) do {                             \
         if (unlikely(!(a))) {                                                                   \
             ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__);        \
             return err_code;                                                                    \
         }                                                                                       \
     } while(0)
-#endif
 
 /**
  * A version of ESP_RETURN_ON_FALSE() macro that can be called from ISR.
  */
-#if defined(CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT)
-#define ESP_RETURN_ON_FALSE_ISR(a, err_code, log_tag, format, ...) do {                         \
-        if (unlikely(!(a))) {                                                                   \
-            return err_code;                                                                    \
-        }                                                                                       \
-    } while(0)
-#else
 #define ESP_RETURN_ON_FALSE_ISR(a, err_code, log_tag, format, ...) do {                         \
         if (unlikely(!(a))) {                                                                   \
             ESP_EARLY_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__);  \
             return err_code;                                                                    \
         }                                                                                       \
     } while(0)
-#endif
 
 /**
  * Macro which can be used to check the condition. If the condition is not 'true', it prints the message,
  * sets the local variable 'ret' to the supplied 'err_code', and then exits by jumping to 'goto_tag'.
  */
-#if defined(CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT)
-#define ESP_GOTO_ON_FALSE(a, err_code, goto_tag, log_tag, format, ...) do {                     \
-        if (unlikely(!(a))) {                                                                   \
-            ret = err_code;                                                                     \
-            goto goto_tag;                                                                      \
-        }                                                                                       \
-    } while (0)
-#else
 #define ESP_GOTO_ON_FALSE(a, err_code, goto_tag, log_tag, format, ...) do {                     \
         if (unlikely(!(a))) {                                                                   \
             ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__);        \
@@ -161,19 +287,10 @@ extern "C" {
             goto goto_tag;                                                                      \
         }                                                                                       \
     } while (0)
-#endif
 
 /**
  * A version of ESP_GOTO_ON_FALSE() macro that can be called from ISR.
  */
-#if defined(CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT)
-#define ESP_GOTO_ON_FALSE_ISR(a, err_code, goto_tag, log_tag, format, ...) do {                 \
-        if (unlikely(!(a))) {                                                                   \
-            ret = err_code;                                                                     \
-            goto goto_tag;                                                                      \
-        }                                                                                       \
-    } while (0)
-#else
 #define ESP_GOTO_ON_FALSE_ISR(a, err_code, goto_tag, log_tag, format, ...) do {                 \
         if (unlikely(!(a))) {                                                                   \
             ESP_EARLY_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__);  \
@@ -181,7 +298,11 @@ extern "C" {
             goto goto_tag;                                                                      \
         }                                                                                       \
     } while (0)
-#endif
+
+#endif // !(defined(__cplusplus) && (__cplusplus >  201703L))
+
+#endif // !CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT
+
 
 #ifdef __cplusplus
 }

+ 16 - 1
components/freertos/port/xtensa/include/freertos/portmacro.h

@@ -308,11 +308,22 @@ static inline void uxPortCompareSetExtram(volatile uint32_t *addr, uint32_t comp
 void vPortYield( void );
 void vPortEvaluateYieldFromISR(int argc, ...);
 void _frxt_setup_switch( void );
+
 /**
  * Macro to count number of arguments of a __VA_ARGS__ used to support portYIELD_FROM_ISR with,
- * or without arguments.
+ * or without arguments. The macro counts only 0 or 1 arguments.
+ *
+ * In the future, we want to switch to C++20. We also want to become compatible with clang.
+ * Hence, we provide two versions of the following macros which are using variadic arguments.
+ * The first one is using the GNU extension ##__VA_ARGS__. The second one is using the C++20 feature __VA_OPT__(,).
+ * This allows users to compile their code with standard C++20 enabled instead of the GNU extension.
+ * Below C++20, we haven't found any good alternative to using ##__VA_ARGS__.
  */
+#if defined(__cplusplus) && (__cplusplus >  201703L)
 #define portGET_ARGUMENT_COUNT(...) portGET_ARGUMENT_COUNT_INNER(0 __VA_OPT__(,) __VA_ARGS__,1,0)
+#else
+#define portGET_ARGUMENT_COUNT(...) portGET_ARGUMENT_COUNT_INNER(0, ##__VA_ARGS__,1,0)
+#endif
 #define portGET_ARGUMENT_COUNT_INNER(zero, one, count, ...) count
 
 _Static_assert(portGET_ARGUMENT_COUNT() == 0, "portGET_ARGUMENT_COUNT() result does not match for 0 arguments");
@@ -325,7 +336,11 @@ _Static_assert(portGET_ARGUMENT_COUNT(1) == 1, "portGET_ARGUMENT_COUNT() result
  *          it was developed to support both usages of portYIELD inside of an ISR. Any other usage form
  *          might result in undesired behaviour
  */
+#if defined(__cplusplus) && (__cplusplus >  201703L)
+#define portYIELD_FROM_ISR(...) vPortEvaluateYieldFromISR(portGET_ARGUMENT_COUNT(__VA_ARGS__) __VA_OPT__(,) __VA_ARGS__)
+#else
 #define portYIELD_FROM_ISR(...) vPortEvaluateYieldFromISR(portGET_ARGUMENT_COUNT(__VA_ARGS__), ##__VA_ARGS__)
+#endif
 
 /* Yielding within an API call (when interrupts are off), means the yield should be delayed
    until interrupts are re-enabled.

+ 81 - 0
components/log/include/esp_log.h

@@ -295,6 +295,26 @@ void esp_log_writev(esp_log_level_t level, const char* tag, const char* format,
 /** @endcond */
 
 /// macro to output logs in startup code, before heap allocator and syscalls have been initialized. log at ``ESP_LOG_ERROR`` level. @see ``printf``,``ESP_LOGE``,``ESP_DRAM_LOGE``
+#define portGET_ARGUMENT_COUNT_INNER(zero, one, count, ...) count
+
+/**
+ * In the future, we want to switch to C++20. We also want to become compatible with clang.
+ * Hence, we provide two versions of the following macros which are using variadic arguments.
+ * The first one is using the GNU extension \#\#__VA_ARGS__. The second one is using the C++20 feature __VA_OPT__(,).
+ * This allows users to compile their code with standard C++20 enabled instead of the GNU extension.
+ * Below C++20, we haven't found any good alternative to using \#\#__VA_ARGS__.
+ */
+#if defined(__cplusplus) && (__cplusplus >  201703L)
+#define ESP_EARLY_LOGE( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_ERROR,   E __VA_OPT__(,) __VA_ARGS__)
+/// macro to output logs in startup code at ``ESP_LOG_WARN`` level.  @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf``
+#define ESP_EARLY_LOGW( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_WARN,    W __VA_OPT__(,) __VA_ARGS__)
+/// macro to output logs in startup code at ``ESP_LOG_INFO`` level.  @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf``
+#define ESP_EARLY_LOGI( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_INFO,    I __VA_OPT__(,) __VA_ARGS__)
+/// macro to output logs in startup code at ``ESP_LOG_DEBUG`` level.  @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf``
+#define ESP_EARLY_LOGD( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_DEBUG,   D __VA_OPT__(,) __VA_ARGS__)
+/// macro to output logs in startup code at ``ESP_LOG_VERBOSE`` level.  @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf``
+#define ESP_EARLY_LOGV( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_VERBOSE, V __VA_OPT__(,) __VA_ARGS__)
+#else // !(defined(__cplusplus) && (__cplusplus >  201703L))
 #define ESP_EARLY_LOGE( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_ERROR,   E, ##__VA_ARGS__)
 /// macro to output logs in startup code at ``ESP_LOG_WARN`` level.  @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf``
 #define ESP_EARLY_LOGW( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_WARN,    W, ##__VA_ARGS__)
@@ -304,6 +324,7 @@ void esp_log_writev(esp_log_level_t level, const char* tag, const char* format,
 #define ESP_EARLY_LOGD( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_DEBUG,   D, ##__VA_ARGS__)
 /// macro to output logs in startup code at ``ESP_LOG_VERBOSE`` level.  @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf``
 #define ESP_EARLY_LOGV( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_VERBOSE, V, ##__VA_ARGS__)
+#endif // !(defined(__cplusplus) && (__cplusplus >  201703L))
 
 #ifdef BOOTLOADER_BUILD
 #define _ESP_LOG_EARLY_ENABLED(log_level) (LOG_LOCAL_LEVEL >= (log_level))
@@ -319,12 +340,21 @@ void esp_log_writev(esp_log_level_t level, const char* tag, const char* format,
         }} while(0)
 
 #ifndef BOOTLOADER_BUILD
+#if defined(__cplusplus) && (__cplusplus >  201703L)
+#define ESP_LOGE( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_ERROR,   tag, format __VA_OPT__(,) __VA_ARGS__)
+#define ESP_LOGW( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_WARN,    tag, format __VA_OPT__(,) __VA_ARGS__)
+#define ESP_LOGI( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_INFO,    tag, format __VA_OPT__(,) __VA_ARGS__)
+#define ESP_LOGD( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_DEBUG,   tag, format __VA_OPT__(,) __VA_ARGS__)
+#define ESP_LOGV( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_VERBOSE, tag, format __VA_OPT__(,) __VA_ARGS__)
+#else // !(defined(__cplusplus) && (__cplusplus >  201703L))
 #define ESP_LOGE( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_ERROR,   tag, format, ##__VA_ARGS__)
 #define ESP_LOGW( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_WARN,    tag, format, ##__VA_ARGS__)
 #define ESP_LOGI( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_INFO,    tag, format, ##__VA_ARGS__)
 #define ESP_LOGD( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_DEBUG,   tag, format, ##__VA_ARGS__)
 #define ESP_LOGV( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_VERBOSE, tag, format, ##__VA_ARGS__)
+#endif // !(defined(__cplusplus) && (__cplusplus >  201703L))
 #else
+
 /**
  * Macro to output logs at ESP_LOG_ERROR level.
  *
@@ -334,6 +364,17 @@ void esp_log_writev(esp_log_level_t level, const char* tag, const char* format,
  *
  * @see ``printf``
  */
+#if defined(__cplusplus) && (__cplusplus >  201703L)
+#define ESP_LOGE( tag, format, ... )  ESP_EARLY_LOGE(tag, format __VA_OPT__(,) __VA_ARGS__)
+/// macro to output logs at ``ESP_LOG_WARN`` level.  @see ``ESP_LOGE``
+#define ESP_LOGW( tag, format, ... )  ESP_EARLY_LOGW(tag, format __VA_OPT__(,) __VA_ARGS__)
+/// macro to output logs at ``ESP_LOG_INFO`` level.  @see ``ESP_LOGE``
+#define ESP_LOGI( tag, format, ... )  ESP_EARLY_LOGI(tag, format __VA_OPT__(,) __VA_ARGS__)
+/// macro to output logs at ``ESP_LOG_DEBUG`` level.  @see ``ESP_LOGE``
+#define ESP_LOGD( tag, format, ... )  ESP_EARLY_LOGD(tag, format __VA_OPT__(,) __VA_ARGS__)
+/// macro to output logs at ``ESP_LOG_VERBOSE`` level.  @see ``ESP_LOGE``
+#define ESP_LOGV( tag, format, ... )  ESP_EARLY_LOGV(tag, format __VA_OPT__(,) __VA_ARGS__)
+#else // !(defined(__cplusplus) && (__cplusplus >  201703L))
 #define ESP_LOGE( tag, format, ... )  ESP_EARLY_LOGE(tag, format, ##__VA_ARGS__)
 /// macro to output logs at ``ESP_LOG_WARN`` level.  @see ``ESP_LOGE``
 #define ESP_LOGW( tag, format, ... )  ESP_EARLY_LOGW(tag, format, ##__VA_ARGS__)
@@ -343,6 +384,7 @@ void esp_log_writev(esp_log_level_t level, const char* tag, const char* format,
 #define ESP_LOGD( tag, format, ... )  ESP_EARLY_LOGD(tag, format, ##__VA_ARGS__)
 /// macro to output logs at ``ESP_LOG_VERBOSE`` level.  @see ``ESP_LOGE``
 #define ESP_LOGV( tag, format, ... )  ESP_EARLY_LOGV(tag, format, ##__VA_ARGS__)
+#endif // !(defined(__cplusplus) && (__cplusplus >  201703L))
 #endif  // BOOTLOADER_BUILD
 
 /** runtime macro to output logs at a specified level.
@@ -354,6 +396,25 @@ void esp_log_writev(esp_log_level_t level, const char* tag, const char* format,
  *
  * @see ``printf``
  */
+#if defined(__cplusplus) && (__cplusplus >  201703L)
+#if CONFIG_LOG_TIMESTAMP_SOURCE_RTOS
+#define ESP_LOG_LEVEL(level, tag, format, ...) do {                     \
+        if (level==ESP_LOG_ERROR )          { esp_log_write(ESP_LOG_ERROR,      tag, LOG_FORMAT(E, format), esp_log_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
+        else if (level==ESP_LOG_WARN )      { esp_log_write(ESP_LOG_WARN,       tag, LOG_FORMAT(W, format), esp_log_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
+        else if (level==ESP_LOG_DEBUG )     { esp_log_write(ESP_LOG_DEBUG,      tag, LOG_FORMAT(D, format), esp_log_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
+        else if (level==ESP_LOG_VERBOSE )   { esp_log_write(ESP_LOG_VERBOSE,    tag, LOG_FORMAT(V, format), esp_log_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
+        else                                { esp_log_write(ESP_LOG_INFO,       tag, LOG_FORMAT(I, format), esp_log_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
+    } while(0)
+#elif CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM
+#define ESP_LOG_LEVEL(level, tag, format, ...) do {                     \
+        if (level==ESP_LOG_ERROR )          { esp_log_write(ESP_LOG_ERROR,      tag, LOG_SYSTEM_TIME_FORMAT(E, format), esp_log_system_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
+        else if (level==ESP_LOG_WARN )      { esp_log_write(ESP_LOG_WARN,       tag, LOG_SYSTEM_TIME_FORMAT(W, format), esp_log_system_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
+        else if (level==ESP_LOG_DEBUG )     { esp_log_write(ESP_LOG_DEBUG,      tag, LOG_SYSTEM_TIME_FORMAT(D, format), esp_log_system_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
+        else if (level==ESP_LOG_VERBOSE )   { esp_log_write(ESP_LOG_VERBOSE,    tag, LOG_SYSTEM_TIME_FORMAT(V, format), esp_log_system_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
+        else                                { esp_log_write(ESP_LOG_INFO,       tag, LOG_SYSTEM_TIME_FORMAT(I, format), esp_log_system_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
+    } while(0)
+#endif //CONFIG_LOG_TIMESTAMP_SOURCE_xxx
+#else // !(defined(__cplusplus) && (__cplusplus >  201703L))
 #if CONFIG_LOG_TIMESTAMP_SOURCE_RTOS
 #define ESP_LOG_LEVEL(level, tag, format, ...) do {                     \
         if (level==ESP_LOG_ERROR )          { esp_log_write(ESP_LOG_ERROR,      tag, LOG_FORMAT(E, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } \
@@ -371,6 +432,7 @@ void esp_log_writev(esp_log_level_t level, const char* tag, const char* format,
         else                                { esp_log_write(ESP_LOG_INFO,       tag, LOG_SYSTEM_TIME_FORMAT(I, format), esp_log_system_timestamp(), tag, ##__VA_ARGS__); } \
     } while(0)
 #endif //CONFIG_LOG_TIMESTAMP_SOURCE_xxx
+#endif // !(defined(__cplusplus) && (__cplusplus >  201703L))
 
 /** runtime macro to output logs at a specified level. Also check the level with ``LOG_LOCAL_LEVEL``.
  *
@@ -397,6 +459,17 @@ void esp_log_writev(esp_log_level_t level, const char* tag, const char* format,
  *
  * @see ``esp_rom_printf``,``ESP_LOGE``
  */
+#if defined(__cplusplus) && (__cplusplus >  201703L)
+#define ESP_DRAM_LOGE( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_ERROR,   E __VA_OPT__(,) __VA_ARGS__)
+/// macro to output logs when the cache is disabled at ``ESP_LOG_WARN`` level.  @see ``ESP_DRAM_LOGW``,``ESP_LOGW``, ``esp_rom_printf``
+#define ESP_DRAM_LOGW( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_WARN,    W __VA_OPT__(,) __VA_ARGS__)
+/// macro to output logs when the cache is disabled at ``ESP_LOG_INFO`` level.  @see ``ESP_DRAM_LOGI``,``ESP_LOGI``, ``esp_rom_printf``
+#define ESP_DRAM_LOGI( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_INFO,    I __VA_OPT__(,) __VA_ARGS__)
+/// macro to output logs when the cache is disabled at ``ESP_LOG_DEBUG`` level.  @see ``ESP_DRAM_LOGD``,``ESP_LOGD``, ``esp_rom_printf``
+#define ESP_DRAM_LOGD( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_DEBUG,   D __VA_OPT__(,) __VA_ARGS__)
+/// macro to output logs when the cache is disabled at ``ESP_LOG_VERBOSE`` level.  @see ``ESP_DRAM_LOGV``,``ESP_LOGV``, ``esp_rom_printf``
+#define ESP_DRAM_LOGV( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_VERBOSE, V __VA_OPT__(,) __VA_ARGS__)
+#else // !(defined(__cplusplus) && (__cplusplus >  201703L))
 #define ESP_DRAM_LOGE( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_ERROR,   E, ##__VA_ARGS__)
 /// macro to output logs when the cache is disabled at ``ESP_LOG_WARN`` level.  @see ``ESP_DRAM_LOGW``,``ESP_LOGW``, ``esp_rom_printf``
 #define ESP_DRAM_LOGW( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_WARN,    W, ##__VA_ARGS__)
@@ -406,14 +479,22 @@ void esp_log_writev(esp_log_level_t level, const char* tag, const char* format,
 #define ESP_DRAM_LOGD( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_DEBUG,   D, ##__VA_ARGS__)
 /// macro to output logs when the cache is disabled at ``ESP_LOG_VERBOSE`` level.  @see ``ESP_DRAM_LOGV``,``ESP_LOGV``, ``esp_rom_printf``
 #define ESP_DRAM_LOGV( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_VERBOSE, V, ##__VA_ARGS__)
+#endif // !(defined(__cplusplus) && (__cplusplus >  201703L))
 
 /** @cond */
 #define _ESP_LOG_DRAM_LOG_FORMAT(letter, format)  DRAM_STR(#letter " %s: " format "\n")
 
+#if defined(__cplusplus) && (__cplusplus >  201703L)
+#define ESP_DRAM_LOG_IMPL(tag, format, log_level, log_tag_letter, ...) do {                                  \
+        if (_ESP_LOG_EARLY_ENABLED(log_level)) {                                                             \
+            esp_rom_printf(_ESP_LOG_DRAM_LOG_FORMAT(log_tag_letter, format), tag __VA_OPT__(,) __VA_ARGS__); \
+        }} while(0)
+#else // !(defined(__cplusplus) && (__cplusplus >  201703L))
 #define ESP_DRAM_LOG_IMPL(tag, format, log_level, log_tag_letter, ...) do {                       \
         if (_ESP_LOG_EARLY_ENABLED(log_level)) {                                                  \
             esp_rom_printf(_ESP_LOG_DRAM_LOG_FORMAT(log_tag_letter, format), tag, ##__VA_ARGS__); \
         }} while(0)
+#endif // !(defined(__cplusplus) && (__cplusplus >  201703L))
 /** @endcond */
 
 #ifdef __cplusplus