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 */