> On Jul 28, 2025, at 10:27 AM, Qing Zhao <qing.z...@oracle.com> wrote: > > > >> On Jul 26, 2025, at 12:43, Yeoul Na <yeoul...@apple.com> wrote: >> >> >> >>> On Jul 24, 2025, at 3:52 PM, Kees Cook <k...@kernel.org> wrote: >>> >>> On Thu, Jul 24, 2025 at 04:26:12PM +0000, Aaron Ballman wrote: >>>> Ah, apologies, I wasn't clear. My thinking is: we're (Clang folks) >>>> going to want it to work in C++ mode because of shared headers. If it >>>> works in C++ mode, then we have to figure out what it means with all >>>> the various C++ features that are possible, not just the use cases >>> >>> I am most familiar with C, so I may be missing something here, but if >>> -fbounds-safety is intended to be C only, then why not just make it >>> unrecognized in C++? >> >> The bounds safety annotations must also be parsable in C++. While C++ can >> get bounds checking by using std::span instead of raw pointers, switching to >> std::span breaks ABI. Therefore, in many situations, C++ code must continue >> to use raw pointers—for example, when interoperating with C code by sharing >> headers with C. In such cases, bounds annotations can help close safety gaps >> in raw pointers. > > -fbound-safety feature was initially proposed as an C extension, So, it’s > natural to make it compatible with C language, not C++. > If C++ also need such a feature, then an extension to C++ is needed too. > If a consistent syntax for this feature can satisfy both C and C++, that > will be ideal. > However, if providing such consistent syntax requires major changes to C > language, > ( a new name lookup scope, and late parsing), it might be a good idea to > provide different syntax for C and C++.
So the main problem here is when the "same code” will be parsed in both in C and C++, which is quite common in practice. Therefore, we need a way to reasonably write code that works both C and C++. From my perspective, that means: 1. The same spelling doesn’t “silently" behave differently in C and C++. 2. At least the most common use cases (i.e., __counted_by(peer)) should be able to be written the same way in C and C++, without ceremony. Here is our compromise proposal that meets these requirements, until we get blessing from the standard for a more elegant solution: 1. `__counted_by(member)` keeps working as is: late parsing + name lookup finds the member name first 2. `__counted_by_expr(expr)` uses a new syntax (e.g., __self), and is not allowed to use a name that matches the member name without the new syntax even if that would’ve resolved to a global variable. Use something like `__global_ref(id)` to disambiguate. This rule will prevent the confusion where `__counted_by_expr(id)` and `__counted_by(id)` may designate different entities. Here are the examples: Ex 1) constexpr int n = 10; struct s { int *__counted_by(n) ptr; // resolves to member `n`; which matches the current behavior int n; }; Ex 2) constexpr int n = 10; struct s { int *__counted_by_expr(n) ptr; // error: referring to a member name without “__self." int n; }; Ex 3) constexpr int n = 10; struct s { int *__counted_by_expr(__self.n) ptr; // resolves to member `n` int n; }; Ex 4) constexpr int n = 10; struct s { int *__counted_by_expr(__self.n + 1) ptr; // resolves to member `n` int n; }; Ex 5) constexpr int n = 10; struct s { int *__counted_by_expr(__global_ref(n) + 1) ptr; // resolves to global `n` int n; }; Ex 6) constexpr int n = 10; struct s { int *__counted_by_expr(n + 1) ptr; // resolves to global `n`; okay, no matching member name }; Or in case, people prefer forward declaration inside `__counted_by_expr()`, the similar rule can apply to achieve the same goal. Yeoul > > Qing >> >> Yeoul >> >> >>> Shared headers don't seem like much of a challenge; >>> e.g. Linux uses macros specifically to avoid mixing illegal syntax into >>> places where it isn't supported. For example, why can't Clang have: >>> >>> #if defined(__cplusplus) >>> # define __counted_by(ARGS...) >>> #else >>> # define __counted_by(ARGS...) __attribute__((counted_by(ARGS))) >>> #endif >>> >>> And then use __counted_by() in all the shared headers? C++ uses will >>> ignore it, and C uses will apply the attributes. >>> >>> It seems weird to me that Clang needs to solve how -fbounds-safety works >>> with C++ if it's not for _use_ in C++. I feel like I'm missing something >>> about features that can't be macro-ified or some ABI issue, but I keep >>> coming up empty. >>> >>> -- >>> Kees Cook