All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] libbpf: fix helper macro C++ compatibility
@ 2026-10-24  3:59 Eduard Zateev
  2026-10-24  4:24 ` sashiko-bot
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Eduard Zateev @ 2026-10-24  3:59 UTC (permalink / raw)
  To: bpf
  Cc: ast, daniel, andrii, eddyz87, memxor, martin.lau, song,
	yonghong.song, jolsa, emil, ihor.solodrai, linux-kernel,
	Eduard Zateev

C++26 warns about the GNU named variadic parameter syntax in
bpf_helpers.h, which prevents consumers from using the header with
-Werror=variadic-macros. Replace the named parameters with __VA_ARGS__.

C++ also rejects implicit conversions used by helper argument packing,
bpf_for_each, and generated helper function pointers. Use explicit
integer and typed pointer casts so these helpers can be parsed and used
from C++.

Verified with GCC and Clang C++26 syntax checks using helper macros,
an ARM64-targeted BPF C smoke build, and generated helper definitions
from scripts/bpf_doc.py. checkpatch.pl reports no errors or warnings.

AI assistance: OpenAI Codex helped reproduce the C++26 failures and
draft changes to tools/lib/bpf/bpf_helpers.h and scripts/bpf_doc.py.
The human submitter must review the changes and test results before
submission.

Fixes: d6a6a55518c1 ("libbpf: Move BPF_SEQ_PRINTF and BPF_SNPRINTF to bpf_helpers.h")
Closes: https://github.com/libbpf/libbpf/issues/974
Signed-off-by: Eduard Zateev <hackerowskiy@gmail.com>
---
 scripts/bpf_doc.py          |  10 +++-
 tools/lib/bpf/bpf_helpers.h | 107 ++++++++++++++++++++++--------------
 2 files changed, 72 insertions(+), 45 deletions(-)

diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py
index 15d113a1b..02e31ad50 100755
--- a/scripts/bpf_doc.py
+++ b/scripts/bpf_doc.py
@@ -829,6 +829,11 @@ class PrinterHelpersHeader(Printer):
 /* Forward declarations of BPF structs */'''
 
         print(header)
+        print("#ifdef __cplusplus")
+        print("#define ___bpf_helper_stub(id, name) reinterpret_cast<decltype(+name)>(id)")
+        print("#else")
+        print("#define ___bpf_helper_stub(id, name) ((void *)(id))")
+        print("#endif")
         for fwd in self.type_fwds:
             print('%s;' % fwd)
         print('')
@@ -849,8 +854,7 @@ class PrinterHelpersHeader(Printer):
             print('')
 
     def print_footer(self):
-        footer = ''
-        print(footer)
+        print("#undef ___bpf_helper_stub")
 
     def map_type(self, t):
         if t in self.known_types:
@@ -908,7 +912,7 @@ class PrinterHelpersHeader(Printer):
             comma = ', '
             print(one_arg, end='')
 
-        print(') = (void *) %d;' % helper.enum_val)
+        print(') = ___bpf_helper_stub(%d, %s);' % (helper.enum_val, proto['name']))
         print('')
 
 
diff --git a/tools/lib/bpf/bpf_helpers.h b/tools/lib/bpf/bpf_helpers.h
index b37b727ef..6c9fdb696 100644
--- a/tools/lib/bpf/bpf_helpers.h
+++ b/tools/lib/bpf/bpf_helpers.h
@@ -233,20 +233,53 @@ enum libbpf_tristate {
 #endif
 
 #define ___bpf_fill0(arr, p, x) do {} while (0)
-#define ___bpf_fill1(arr, p, x) arr[p] = x
-#define ___bpf_fill2(arr, p, x, args...) arr[p] = x; ___bpf_fill1(arr, p + 1, args)
-#define ___bpf_fill3(arr, p, x, args...) arr[p] = x; ___bpf_fill2(arr, p + 1, args)
-#define ___bpf_fill4(arr, p, x, args...) arr[p] = x; ___bpf_fill3(arr, p + 1, args)
-#define ___bpf_fill5(arr, p, x, args...) arr[p] = x; ___bpf_fill4(arr, p + 1, args)
-#define ___bpf_fill6(arr, p, x, args...) arr[p] = x; ___bpf_fill5(arr, p + 1, args)
-#define ___bpf_fill7(arr, p, x, args...) arr[p] = x; ___bpf_fill6(arr, p + 1, args)
-#define ___bpf_fill8(arr, p, x, args...) arr[p] = x; ___bpf_fill7(arr, p + 1, args)
-#define ___bpf_fill9(arr, p, x, args...) arr[p] = x; ___bpf_fill8(arr, p + 1, args)
-#define ___bpf_fill10(arr, p, x, args...) arr[p] = x; ___bpf_fill9(arr, p + 1, args)
-#define ___bpf_fill11(arr, p, x, args...) arr[p] = x; ___bpf_fill10(arr, p + 1, args)
-#define ___bpf_fill12(arr, p, x, args...) arr[p] = x; ___bpf_fill11(arr, p + 1, args)
-#define ___bpf_fill(arr, args...) \
-	___bpf_apply(___bpf_fill, ___bpf_narg(args))(arr, 0, args)
+#define ___bpf_fill1(arr, p, x) (arr[p] = (unsigned long long)(x))
+#define ___bpf_fill2(arr, p, x, ...) do { \
+	arr[p] = (unsigned long long)(x); \
+	___bpf_fill1(arr, p + 1, __VA_ARGS__); \
+} while (0)
+#define ___bpf_fill3(arr, p, x, ...) do { \
+	arr[p] = (unsigned long long)(x); \
+	___bpf_fill2(arr, p + 1, __VA_ARGS__); \
+} while (0)
+#define ___bpf_fill4(arr, p, x, ...) do { \
+	arr[p] = (unsigned long long)(x); \
+	___bpf_fill3(arr, p + 1, __VA_ARGS__); \
+} while (0)
+#define ___bpf_fill5(arr, p, x, ...) do { \
+	arr[p] = (unsigned long long)(x); \
+	___bpf_fill4(arr, p + 1, __VA_ARGS__); \
+} while (0)
+#define ___bpf_fill6(arr, p, x, ...) do { \
+	arr[p] = (unsigned long long)(x); \
+	___bpf_fill5(arr, p + 1, __VA_ARGS__); \
+} while (0)
+#define ___bpf_fill7(arr, p, x, ...) do { \
+	arr[p] = (unsigned long long)(x); \
+	___bpf_fill6(arr, p + 1, __VA_ARGS__); \
+} while (0)
+#define ___bpf_fill8(arr, p, x, ...) do { \
+	arr[p] = (unsigned long long)(x); \
+	___bpf_fill7(arr, p + 1, __VA_ARGS__); \
+} while (0)
+#define ___bpf_fill9(arr, p, x, ...) do { \
+	arr[p] = (unsigned long long)(x); \
+	___bpf_fill8(arr, p + 1, __VA_ARGS__); \
+} while (0)
+#define ___bpf_fill10(arr, p, x, ...) do { \
+	arr[p] = (unsigned long long)(x); \
+	___bpf_fill9(arr, p + 1, __VA_ARGS__); \
+} while (0)
+#define ___bpf_fill11(arr, p, x, ...) do { \
+	arr[p] = (unsigned long long)(x); \
+	___bpf_fill10(arr, p + 1, __VA_ARGS__); \
+} while (0)
+#define ___bpf_fill12(arr, p, x, ...) do { \
+	arr[p] = (unsigned long long)(x); \
+	___bpf_fill11(arr, p + 1, __VA_ARGS__); \
+} while (0)
+#define ___bpf_fill(arr, ...) \
+	___bpf_apply(___bpf_fill, ___bpf_narg(__VA_ARGS__))(arr, 0, __VA_ARGS__)
 
 /*
  * Format strings are in a section of their own. When global data of the object
@@ -260,15 +293,12 @@ enum libbpf_tristate {
  * BPF_SEQ_PRINTF to wrap bpf_seq_printf to-be-printed values
  * in a structure.
  */
-#define BPF_SEQ_PRINTF(seq, fmt, args...)			\
+#define BPF_SEQ_PRINTF(seq, fmt, ...)			\
 ({								\
 	static const char ___fmt[] ___bpf_fmt_sec = fmt;	\
-	unsigned long long ___param[___bpf_narg(args)];		\
+	unsigned long long ___param[___bpf_narg(__VA_ARGS__)];		\
 								\
-	_Pragma("GCC diagnostic push")				\
-	_Pragma("GCC diagnostic ignored \"-Wint-conversion\"")	\
-	___bpf_fill(___param, args);				\
-	_Pragma("GCC diagnostic pop")				\
+	___bpf_fill(___param, __VA_ARGS__);				\
 								\
 	bpf_seq_printf(seq, ___fmt, sizeof(___fmt),		\
 		       ___param, sizeof(___param));		\
@@ -278,15 +308,12 @@ enum libbpf_tristate {
  * BPF_SNPRINTF wraps the bpf_snprintf helper with variadic arguments instead of
  * an array of u64.
  */
-#define BPF_SNPRINTF(out, out_size, fmt, args...)		\
+#define BPF_SNPRINTF(out, out_size, fmt, ...)		\
 ({								\
 	static const char ___fmt[] ___bpf_fmt_sec = fmt;	\
-	unsigned long long ___param[___bpf_narg(args)];		\
+	unsigned long long ___param[___bpf_narg(__VA_ARGS__)];		\
 								\
-	_Pragma("GCC diagnostic push")				\
-	_Pragma("GCC diagnostic ignored \"-Wint-conversion\"")	\
-	___bpf_fill(___param, args);				\
-	_Pragma("GCC diagnostic pop")				\
+	___bpf_fill(___param, __VA_ARGS__);				\
 								\
 	bpf_snprintf(out, out_size, ___fmt,			\
 		     ___param, sizeof(___param));		\
@@ -309,29 +336,23 @@ enum libbpf_tristate {
  * __bpf_vprintk wraps the bpf_trace_vprintk helper with variadic arguments
  * instead of an array of u64.
  */
-#define __bpf_vprintk(fmt, args...)				\
+#define __bpf_vprintk(fmt, ...)				\
 ({								\
 	static const char ___fmt[] ___bpf_fmt_sec = fmt;	\
-	unsigned long long ___param[___bpf_narg(args)];		\
+	unsigned long long ___param[___bpf_narg(__VA_ARGS__)];		\
 								\
-	_Pragma("GCC diagnostic push")				\
-	_Pragma("GCC diagnostic ignored \"-Wint-conversion\"")	\
-	___bpf_fill(___param, args);				\
-	_Pragma("GCC diagnostic pop")				\
+	___bpf_fill(___param, __VA_ARGS__);				\
 								\
 	bpf_trace_vprintk(___fmt, sizeof(___fmt),		\
 			  ___param, sizeof(___param));		\
 })
 
-#define bpf_stream_printk(stream_id, fmt, args...)					\
+#define bpf_stream_printk(stream_id, fmt, ...)					\
 ({											\
 	static const char ___fmt[] ___bpf_fmt_sec = fmt;				\
-	unsigned long long ___param[___bpf_narg(args)];					\
+	unsigned long long ___param[___bpf_narg(__VA_ARGS__)];					\
 											\
-	_Pragma("GCC diagnostic push")							\
-	_Pragma("GCC diagnostic ignored \"-Wint-conversion\"")				\
-	___bpf_fill(___param, args);							\
-	_Pragma("GCC diagnostic pop")							\
+	___bpf_fill(___param, __VA_ARGS__);							\
 											\
 	bpf_stream_vprintk(stream_id, ___fmt, ___param, sizeof(___param));		\
 })
@@ -346,7 +367,7 @@ enum libbpf_tristate {
 		   __bpf_printk /*1*/, __bpf_printk /*0*/)
 
 /* Helper macro to print out debug messages */
-#define bpf_printk(fmt, args...) ___bpf_pick_printk(args)(fmt, ##args)
+#define bpf_printk(fmt, ...) ___bpf_pick_printk(__VA_ARGS__)(fmt, ##__VA_ARGS__)
 
 struct bpf_iter_num;
 
@@ -382,16 +403,18 @@ extern void bpf_iter_num_destroy(struct bpf_iter_num *it) __weak __ksym;
  * extension: __attribute__((cleanup(<func>))), supported by both GCC and
  * Clang.
  */
-#define bpf_for_each(type, cur, args...) for (							\
+#define bpf_for_each(type, cur, ...) for (							\
 	/* initialize and define destructor */							\
 	struct bpf_iter_##type ___it __attribute__((aligned(8), /* enforce, just in case */,	\
 						    cleanup(bpf_iter_##type##_destroy))),	\
 	/* ___p pointer is just to call bpf_iter_##type##_new() *once* to init ___it */		\
 			       *___p __attribute__((unused)) = (				\
-					bpf_iter_##type##_new(&___it, ##args),			\
+						bpf_iter_##type##_new(&___it, \
+								       ##__VA_ARGS__), \
 	/* this is a workaround for Clang bug: it currently doesn't emit BTF */			\
 	/* for bpf_iter_##type##_destroy() when used from cleanup() attribute */		\
-					(void)bpf_iter_##type##_destroy, (void *)0);		\
+					(void)bpf_iter_##type##_destroy, \
+					(struct bpf_iter_##type *)0); \
 	/* iteration and termination check */							\
 	(((cur) = bpf_iter_##type##_next(&___it)));						\
 )
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] libbpf: fix helper macro C++ compatibility
  2026-10-24  3:59 [PATCH] libbpf: fix helper macro C++ compatibility Eduard Zateev
@ 2026-10-24  4:24 ` sashiko-bot
  2026-10-24  4:36 ` bot+bpf-ci
  2026-10-24 19:16 ` Alexei Starovoitov
  2 siblings, 0 replies; 4+ messages in thread
From: sashiko-bot @ 2026-10-24  4:24 UTC (permalink / raw)
  To: Eduard Zateev, bpf

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Low] libbpf: C++ build failure in bpf_for() and bpf_repeat() due to (void *)0
- [Low] libbpf: missing extern C linkage on bpf_iter_num_*() in bpf_helpers.h
--

commit 7e0b0adc8984c99351ff40e7c423f83f7d25ccab
Author: Eduard Zateev <hackerowskiy@gmail.com>

libbpf: fix helper macro C++ compatibility

This commit replaces GNU named variadic macro parameters in bpf_helpers.h with
__VA_ARGS__ to avoid C++26 variadic macro warnings. It also adds explicit
integer and typed pointer casts to helper macros and generated helper stubs so
that bpf_helpers.h and bpf_helper_defs.h can be used from C++.

> diff --git a/tools/lib/bpf/bpf_helpers.h b/tools/lib/bpf/bpf_helpers.h
> index b37b727ef216f..6c9fdb69661ea 100644
> --- a/tools/lib/bpf/bpf_helpers.h
> +++ b/tools/lib/bpf/bpf_helpers.h

[ ... ]

> @@ -346,7 +367,7 @@ enum libbpf_tristate {
>  		   __bpf_printk /*1*/, __bpf_printk /*0*/)
>  
>  /* Helper macro to print out debug messages */
> -#define bpf_printk(fmt, args...) ___bpf_pick_printk(args)(fmt, ##args)
> +#define bpf_printk(fmt, ...) ___bpf_pick_printk(__VA_ARGS__)(fmt, ##__VA_ARGS__)
>  
>  struct bpf_iter_num;
>  

[Severity: Low]
When tools/lib/bpf/bpf_helpers.h is included directly in a C++ translation
unit without an outer extern "C" block, these kfunc declarations immediately
below struct bpf_iter_num have C++ linkage:

extern int bpf_iter_num_new(struct bpf_iter_num *it, int start, int end) __weak __ksym;
extern int *bpf_iter_num_next(struct bpf_iter_num *it) __weak __ksym;
extern void bpf_iter_num_destroy(struct bpf_iter_num *it) __weak __ksym;

When bpf_for_each(num, cur, start, end) is expanded in C++, the compiler emits
mangled ELF symbol names for bpf_iter_num_new(), bpf_iter_num_next(), and
bpf_iter_num_destroy() in .symtab, which causes bpf_object__collect_externs()
 -> find_extern_btf_id() and kernel BTF kfunc resolution in libbpf to fail
with -ENOENT.

Should bpf_helpers.h wrap its extern declarations in an #ifdef __cplusplus
extern "C" guard, similar to the other headers in tools/lib/bpf/?

> @@ -382,16 +403,18 @@ extern void bpf_iter_num_destroy(struct bpf_iter_num *it) __weak __ksym;
>   * extension: __attribute__((cleanup(<func>))), supported by both GCC and
>   * Clang.
>   */
> -#define bpf_for_each(type, cur, args...) for (							\
> +#define bpf_for_each(type, cur, ...) for (							\
>  	/* initialize and define destructor */							\
>  	struct bpf_iter_##type ___it __attribute__((aligned(8), /* enforce, just in case */,	\
>  						    cleanup(bpf_iter_##type##_destroy))),	\
>  	/* ___p pointer is just to call bpf_iter_##type##_new() *once* to init ___it */		\
>  			       *___p __attribute__((unused)) = (				\
> -					bpf_iter_##type##_new(&___it, ##args),			\
> +						bpf_iter_##type##_new(&___it, \
> +								       ##__VA_ARGS__), \
>  	/* this is a workaround for Clang bug: it currently doesn't emit BTF */			\
>  	/* for bpf_iter_##type##_destroy() when used from cleanup() attribute */		\
> -					(void)bpf_iter_##type##_destroy, (void *)0);		\
> +					(void)bpf_iter_##type##_destroy, \
> +					(struct bpf_iter_##type *)0); \

[Severity: Low]
Here bpf_for_each() is updated to initialize ___p with
(struct bpf_iter_##type *)0 instead of (void *)0, since C++ rejects implicit
conversion from void * to a typed pointer.

However, the companion macros bpf_for() and bpf_repeat() immediately below in
tools/lib/bpf/bpf_helpers.h still initialize struct bpf_iter_num *___p with
(void *)0:

#define bpf_for(i, start, end) for (								\
	...
			    *___p __attribute__((unused)) = (					\
				bpf_iter_num_new(&___it, (start), (end)),			\
				(void)bpf_iter_num_destroy, (void *)0);				\

and:

#define bpf_repeat(N) for (									\
	...
			    *___p __attribute__((unused)) = (					\
				bpf_iter_num_new(&___it, 0, (N)),				\
				(void)bpf_iter_num_destroy, (void *)0);				\

Would expanding bpf_for() or bpf_repeat() in C++ still fail to compile unless
those initializers are also cast to (struct bpf_iter_num *)0?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261024035902.44566-1-hackerowskiy@gmail.com?part=1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] libbpf: fix helper macro C++ compatibility
  2026-10-24  3:59 [PATCH] libbpf: fix helper macro C++ compatibility Eduard Zateev
  2026-10-24  4:24 ` sashiko-bot
@ 2026-10-24  4:36 ` bot+bpf-ci
  2026-10-24 19:16 ` Alexei Starovoitov
  2 siblings, 0 replies; 4+ messages in thread
From: bot+bpf-ci @ 2026-10-24  4:36 UTC (permalink / raw)
  To: hackerowskiy, bpf
  Cc: ast, daniel, andrii, eddyz87, memxor, martin.lau, song,
	yonghong.song, jolsa, emil, ihor.solodrai, linux-kernel,
	hackerowskiy, ast, andrii, daniel, martin.lau, eddyz87,
	yonghong.song, mason, ihor.solodrai

[-- Attachment #1: Type: text/plain, Size: 6125 bytes --]

> libbpf: fix helper macro C++ compatibility

TL;DR:
- bpf_for() and bpf_repeat() may still fail to compile in C++ (void *
  initializer left unchanged)
- Fixes: tag looks inaccurate and would pull this into stable trees
- Nit: generated-header comment misplaced

>     libbpf: fix helper macro C++ compatibility
>
>     C++26 warns about the GNU named variadic parameter syntax in
>     bpf_helpers.h, which prevents consumers from using the header with
>     -Werror=variadic-macros. Replace the named parameters with __VA_ARGS__.
>
>     C++ also rejects implicit conversions used by helper argument packing,
>     bpf_for_each, and generated helper function pointers. Use explicit
>     integer and typed pointer casts so these helpers can be parsed and used
>     from C++.
>
>     Verified with GCC and Clang C++26 syntax checks using helper macros,
>     an ARM64-targeted BPF C smoke build, and generated helper definitions
>     from scripts/bpf_doc.py. checkpatch.pl reports no errors or warnings.
>
>     AI assistance: OpenAI Codex helped reproduce the C++26 failures and
>     draft changes to tools/lib/bpf/bpf_helpers.h and scripts/bpf_doc.py.
>     The human submitter must review the changes and test results before
>     submission.
>
>     Fixes: d6a6a55518c1 ("libbpf: Move BPF_SEQ_PRINTF and BPF_SNPRINTF to bpf_helpers.h")
>     Closes: https://github.com/libbpf/libbpf/issues/974
>     Signed-off-by: Eduard Zateev <hackerowskiy@gmail.com>

Is this Fixes: tag accurate?

d6a6a55518c1 only moved BPF_SEQ_PRINTF and BPF_SNPRINTF from bpf_tracing.h
to bpf_helpers.h.  Their args... syntax came from c09add2fbc5a
("tools/libbpf: Add bpf_iter support").

The other constructs changed here came from different commits:

  - bpf_printk()'s args... and ##args from c2758baa9798 ("libbpf: Modify
    bpf_printk to choose helper based on arg count")
  - bpf_for_each()'s (void *)0 initializer from the open-coded iterator
    work, moved into bpf_helpers.h by c5e647416708
  - the "(void *) %d" helper initializer in the generated header from
    7a387bed47f7 ("scripts/bpf: teach bpf_helpers_doc.py to dump BPF
    helper definitions")

None of those commits broke C++ support for the header.  It never had C++
support, so this patch looks like it adds it rather than fixing a
regression.

The tag would also mark this change for stable trees back to v5.14, many of
which do not have bpf_for_each(), bpf_stream_printk() or __bpf_vprintk().

Should the Fixes: tag be dropped, given that Closes: already gives the
motivation?

> diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py
> index 15d113a1bc1d..02e31ad509af 100755
> --- a/scripts/bpf_doc.py
> +++ b/scripts/bpf_doc.py
> @@ -829,6 +829,11 @@ class PrinterHelpersHeader(Printer):
>  /* Forward declarations of BPF structs */'''
>  
>          print(header)
> +        print("#ifdef __cplusplus")
> +        print("#define ___bpf_helper_stub(id, name) reinterpret_cast<decltype(+name)>(id)")
> +        print("#else")
> +        print("#define ___bpf_helper_stub(id, name) ((void *)(id))")
> +        print("#endif")
>          for fwd in self.type_fwds:
>              print('%s;' % fwd)
>          print('')

This isn't a bug, but the header string ends with the comment
"/* Forward declarations of BPF structs */", and this new block is printed
right after it, before the struct declarations.  The generated
bpf_helper_defs.h now reads:

    /* Forward declarations of BPF structs */
    #ifdef __cplusplus
    #define ___bpf_helper_stub(id, name) reinterpret_cast<decltype(+name)>(id)
    #else
    #define ___bpf_helper_stub(id, name) ((void *)(id))
    #endif
    struct bpf_fib_lookup;

So the comment now sits on top of the macro block instead of the forward
declarations.  Could the #ifdef block be printed before the comment, or after
the forward declarations and the blank line, so the comment stays next to the
declarations it describes?

[ ... ]

> @@ -382,16 +403,18 @@ extern void bpf_iter_num_destroy(struct bpf_iter_num *it) __weak __ksym;
>   * extension: __attribute__((cleanup(<func>))), supported by both GCC and
>   * Clang.
>   */
> -#define bpf_for_each(type, cur, args...) for (							\
> +#define bpf_for_each(type, cur, ...) for (							\
>  	/* initialize and define destructor */							\
>  	struct bpf_iter_##type ___it __attribute__((aligned(8), /* enforce, just in case */,	\
>  						    cleanup(bpf_iter_##type##_destroy))),	\
>  	/* ___p pointer is just to call bpf_iter_##type##_new() *once* to init ___it */		\
>  			       *___p __attribute__((unused)) = (				\
> -					bpf_iter_##type##_new(&___it, ##args),			\
> +						bpf_iter_##type##_new(&___it, \
> +								       ##__VA_ARGS__), \
>  	/* this is a workaround for Clang bug: it currently doesn't emit BTF */			\
>  	/* for bpf_iter_##type##_destroy() when used from cleanup() attribute */		\
> -					(void)bpf_iter_##type##_destroy, (void *)0);		\
> +					(void)bpf_iter_##type##_destroy, \
> +					(struct bpf_iter_##type *)0); \
>  	/* iteration and termination check */							\
>  	(((cur) = bpf_iter_##type##_next(&___it)));						\
>  )

The commit message says C++ rejects the implicit conversions used by
bpf_for_each(), and this changes its ___p initializer from (void *)0 to
(struct bpf_iter_##type *)0.  The sibling macros bpf_for() and bpf_repeat()
still end their ___p initializer with:

    (void)bpf_iter_num_destroy, (void *)0);

___p is declared as struct bpf_iter_num * there (in the same declaration as
___it), and C++ does not allow an implicit conversion from void * to
struct bpf_iter_num *.

Won't a C++ BPF program that uses bpf_for(i, 0, N) or bpf_repeat(N) still
fail to compile with the same error this patch fixes for bpf_for_each()?
Since the stated goal is that "these helpers can be parsed and used from
C++", should bpf_for() and bpf_repeat() get the same
(struct bpf_iter_num *)0 change?


---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md

CI run summary: https://github.com/kernel-patches/bpf/actions/runs/40061559445

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] libbpf: fix helper macro C++ compatibility
  2026-10-24  3:59 [PATCH] libbpf: fix helper macro C++ compatibility Eduard Zateev
  2026-10-24  4:24 ` sashiko-bot
  2026-10-24  4:36 ` bot+bpf-ci
@ 2026-10-24 19:16 ` Alexei Starovoitov
  2 siblings, 0 replies; 4+ messages in thread
From: Alexei Starovoitov @ 2026-10-24 19:16 UTC (permalink / raw)
  To: Eduard Zateev, bpf
  Cc: daniel, andrii, eddyz87, memxor, martin.lau, song, yonghong.song,
	jolsa, emil, ihor.solodrai, linux-kernel

On Fri, Oct 23, 2026 at 08:59 PM Eduard Zateev <hackerowskiy@gmail.com> wrote:
> The human submitter must review the changes and test results before
> submission.

ouch. did you read what AI generated for you?

The reason for rejection is the same as before.
You're stratching the surface without thinking.
Pls stop sending such patches.

pw-bot: cr

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-10-24 19:16 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-24  3:59 [PATCH] libbpf: fix helper macro C++ compatibility Eduard Zateev
2026-10-24  4:24 ` sashiko-bot
2026-10-24  4:36 ` bot+bpf-ci
2026-10-24 19:16 ` Alexei Starovoitov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.