This is an automated email from the ASF dual-hosted git repository.

GUIDINGLI pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 2a6454438db include/macro.h: fix REVERSE_ARG/FOREACH_ARG for empty 
args in C++
2a6454438db is described below

commit 2a6454438dbd32b19dd160de9af2cf7ee7d374df
Author: Xiang Xiao <[email protected]>
AuthorDate: Fri Aug 21 21:56:56 2026 +0800

    include/macro.h: fix REVERSE_ARG/FOREACH_ARG for empty args in C++
    
    C++ strict mode drops the GNU ", ##__VA_ARGS__" comma elision, so
    GET_ARG_COUNT() and REVERSE_ARG() misselect their dispatch entry with
    zero varargs. Centralize the empty-argument handling in GET_ARG_COUNT
    (via __VA_OPT__ for C++) and make REVERSE_ARG and FOREACH_ARG dispatch
    through CONCATENATE(prefix, GET_ARG_COUNT(...)), removing the two
    duplicated 33-entry selector lists.
    
    Signed-off-by: Xiang Xiao <[email protected]>
---
 include/nuttx/macro.h | 89 +++++++++++++++++++++++++++------------------------
 1 file changed, 47 insertions(+), 42 deletions(-)

diff --git a/include/nuttx/macro.h b/include/nuttx/macro.h
index 6c38aba4b24..4b37681b6ad 100644
--- a/include/nuttx/macro.h
+++ b/include/nuttx/macro.h
@@ -41,13 +41,28 @@
                       _24, _25, _26, _27, _28, _29, _30, _31, \
                       _32, name, ...) name
 
-/* Get the number of arguments (up to 32) */
-
-#define GET_ARG_COUNT(...) \
+/* Get the number of arguments (up to 32)
+ *
+ * C++ strict mode drops the GNU ", ##__VA_ARGS__" comma elision, which
+ * would shift the selector off by one for the zero-argument case; use the
+ * standard __VA_OPT__ there instead.  This is the only place where the
+ * empty-argument case needs special handling: every higher-level macro
+ * (REVERSE_ARG, FOREACH_ARG, ...) dispatches on top of GET_ARG_COUNT.
+ */
+
+#if defined(__cplusplus)
+#  define GET_ARG_COUNT(...) \
+        GET_ARG_VALUE(_0 __VA_OPT__(,) __VA_ARGS__, 32, 31, 30, \
+        29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \
+        19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \
+        9,  8,  7,  6,  5,  4,  3,  2,  1,  0)
+#else
+#  define GET_ARG_COUNT(...) \
         GET_ARG_VALUE(_0, ##__VA_ARGS__, 32, 31, 30, \
         29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \
         19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \
         9,  8,  7,  6,  5,  4,  3,  2,  1,  0)
+#endif
 
 /* Expand the arguments */
 
@@ -56,17 +71,17 @@
 
 /* Reverse the arguments */
 
-#define REVERSE_00()
-#define REVERSE_01(a)     a
-#define REVERSE_02(a,b)   b,a
-#define REVERSE_03(a,...) EXPAND(REVERSE_02(__VA_ARGS__)),a
-#define REVERSE_04(a,...) EXPAND(REVERSE_03(__VA_ARGS__)),a
-#define REVERSE_05(a,...) EXPAND(REVERSE_04(__VA_ARGS__)),a
-#define REVERSE_06(a,...) EXPAND(REVERSE_05(__VA_ARGS__)),a
-#define REVERSE_07(a,...) EXPAND(REVERSE_06(__VA_ARGS__)),a
-#define REVERSE_08(a,...) EXPAND(REVERSE_07(__VA_ARGS__)),a
-#define REVERSE_09(a,...) EXPAND(REVERSE_08(__VA_ARGS__)),a
-#define REVERSE_10(a,...) EXPAND(REVERSE_09(__VA_ARGS__)),a
+#define REVERSE_0()
+#define REVERSE_1(a)     a
+#define REVERSE_2(a,b)   b,a
+#define REVERSE_3(a,...) EXPAND(REVERSE_2(__VA_ARGS__)),a
+#define REVERSE_4(a,...) EXPAND(REVERSE_3(__VA_ARGS__)),a
+#define REVERSE_5(a,...) EXPAND(REVERSE_4(__VA_ARGS__)),a
+#define REVERSE_6(a,...) EXPAND(REVERSE_5(__VA_ARGS__)),a
+#define REVERSE_7(a,...) EXPAND(REVERSE_6(__VA_ARGS__)),a
+#define REVERSE_8(a,...) EXPAND(REVERSE_7(__VA_ARGS__)),a
+#define REVERSE_9(a,...) EXPAND(REVERSE_8(__VA_ARGS__)),a
+#define REVERSE_10(a,...) EXPAND(REVERSE_9(__VA_ARGS__)),a
 #define REVERSE_11(a,...) EXPAND(REVERSE_10(__VA_ARGS__)),a
 #define REVERSE_12(a,...) EXPAND(REVERSE_11(__VA_ARGS__)),a
 #define REVERSE_13(a,...) EXPAND(REVERSE_12(__VA_ARGS__)),a
@@ -90,30 +105,26 @@
 #define REVERSE_31(a,...) EXPAND(REVERSE_30(__VA_ARGS__)),a
 #define REVERSE_32(a,...) EXPAND(REVERSE_31(__VA_ARGS__)),a
 
-#define REVERSE_ARG_(...) \
-        GET_ARG_VALUE(0, ##__VA_ARGS__, \
-        REVERSE_32, REVERSE_31, REVERSE_30, REVERSE_29, REVERSE_28, 
REVERSE_27, \
-        REVERSE_26, REVERSE_25, REVERSE_24, REVERSE_23, REVERSE_22, 
REVERSE_21, \
-        REVERSE_20, REVERSE_19, REVERSE_18, REVERSE_17, REVERSE_16, 
REVERSE_15, \
-        REVERSE_14, REVERSE_13, REVERSE_12, REVERSE_11, REVERSE_10, 
REVERSE_09, \
-        REVERSE_08, REVERSE_07, REVERSE_06, REVERSE_05, REVERSE_04, 
REVERSE_03, \
-        REVERSE_02, REVERSE_01, REVERSE_00)(__VA_ARGS__)
+/* Select the worker through GET_ARG_COUNT so the zero-argument case
+ * expands correctly in both C and C++ (see GET_ARG_COUNT).
+ */
 
-#define REVERSE_ARG(...) REVERSE_ARG_(##__VA_ARGS__)
+#define REVERSE_ARG(...) \
+        CONCATENATE(REVERSE_, GET_ARG_COUNT(__VA_ARGS__))(__VA_ARGS__)
 
 /* Apply the macro to each argument */
 
-#define FOREACH_00(action, count, param, ...)      0
-#define FOREACH_01(action, count, param, arg, ...) action(param, arg, count - 
1 )
-#define FOREACH_02(action, count, param, arg, ...) action(param, arg, count - 
2 ) FOREACH_01(action, count, param, __VA_ARGS__)
-#define FOREACH_03(action, count, param, arg, ...) action(param, arg, count - 
3 ) FOREACH_02(action, count, param, __VA_ARGS__)
-#define FOREACH_04(action, count, param, arg, ...) action(param, arg, count - 
4 ) FOREACH_03(action, count, param, __VA_ARGS__)
-#define FOREACH_05(action, count, param, arg, ...) action(param, arg, count - 
5 ) FOREACH_04(action, count, param, __VA_ARGS__)
-#define FOREACH_06(action, count, param, arg, ...) action(param, arg, count - 
6 ) FOREACH_05(action, count, param, __VA_ARGS__)
-#define FOREACH_07(action, count, param, arg, ...) action(param, arg, count - 
7 ) FOREACH_06(action, count, param, __VA_ARGS__)
-#define FOREACH_08(action, count, param, arg, ...) action(param, arg, count - 
8 ) FOREACH_07(action, count, param, __VA_ARGS__)
-#define FOREACH_09(action, count, param, arg, ...) action(param, arg, count - 
9 ) FOREACH_08(action, count, param, __VA_ARGS__)
-#define FOREACH_10(action, count, param, arg, ...) action(param, arg, count - 
10) FOREACH_09(action, count, param, __VA_ARGS__)
+#define FOREACH_0(action, count, param, ...)      0
+#define FOREACH_1(action, count, param, arg, ...) action(param, arg, count - 1 
)
+#define FOREACH_2(action, count, param, arg, ...) action(param, arg, count - 2 
) FOREACH_1(action, count, param, __VA_ARGS__)
+#define FOREACH_3(action, count, param, arg, ...) action(param, arg, count - 3 
) FOREACH_2(action, count, param, __VA_ARGS__)
+#define FOREACH_4(action, count, param, arg, ...) action(param, arg, count - 4 
) FOREACH_3(action, count, param, __VA_ARGS__)
+#define FOREACH_5(action, count, param, arg, ...) action(param, arg, count - 5 
) FOREACH_4(action, count, param, __VA_ARGS__)
+#define FOREACH_6(action, count, param, arg, ...) action(param, arg, count - 6 
) FOREACH_5(action, count, param, __VA_ARGS__)
+#define FOREACH_7(action, count, param, arg, ...) action(param, arg, count - 7 
) FOREACH_6(action, count, param, __VA_ARGS__)
+#define FOREACH_8(action, count, param, arg, ...) action(param, arg, count - 8 
) FOREACH_7(action, count, param, __VA_ARGS__)
+#define FOREACH_9(action, count, param, arg, ...) action(param, arg, count - 9 
) FOREACH_8(action, count, param, __VA_ARGS__)
+#define FOREACH_10(action, count, param, arg, ...) action(param, arg, count - 
10) FOREACH_9(action, count, param, __VA_ARGS__)
 #define FOREACH_11(action, count, param, arg, ...) action(param, arg, count - 
11) FOREACH_10(action, count, param, __VA_ARGS__)
 #define FOREACH_12(action, count, param, arg, ...) action(param, arg, count - 
12) FOREACH_11(action, count, param, __VA_ARGS__)
 #define FOREACH_13(action, count, param, arg, ...) action(param, arg, count - 
13) FOREACH_12(action, count, param, __VA_ARGS__)
@@ -138,15 +149,9 @@
 #define FOREACH_32(action, count, param, arg, ...) action(param, arg, count - 
32) FOREACH_31(action, count, param, __VA_ARGS__)
 
 #define FOREACH_ARG_(action, count, param, ...) \
-        GET_ARG_VALUE(0, ##__VA_ARGS__, \
-        FOREACH_32, FOREACH_31, FOREACH_30, FOREACH_29, FOREACH_28, 
FOREACH_27, \
-        FOREACH_26, FOREACH_25, FOREACH_24, FOREACH_23, FOREACH_22, 
FOREACH_21, \
-        FOREACH_20, FOREACH_19, FOREACH_18, FOREACH_17, FOREACH_16, 
FOREACH_15, \
-        FOREACH_14, FOREACH_13, FOREACH_12, FOREACH_11, FOREACH_10, 
FOREACH_09, \
-        FOREACH_08, FOREACH_07, FOREACH_06, FOREACH_05, FOREACH_04, 
FOREACH_03, \
-        FOREACH_02, FOREACH_01, FOREACH_00)(action, count, param, 
##__VA_ARGS__)
+        CONCATENATE(FOREACH_, count)(action, count, param, __VA_ARGS__)
 
 #define FOREACH_ARG(action, param, ...) \
-        FOREACH_ARG_(action, GET_ARG_COUNT(__VA_ARGS__), param, ##__VA_ARGS__)
+        FOREACH_ARG_(action, GET_ARG_COUNT(__VA_ARGS__), param, __VA_ARGS__)
 
 #endif /* __INCLUDE_NUTTX_MACRO_H */

Reply via email to