In macros it is common to declare local variables using typeof(param) in order
to ensure that side effects are only evaluated once.  A consequence of this is
double textural expansion of the parameter, which can get out of hand very
quickly with nested macros.
A GCC extension, __auto_type, is now avaialble in the new toolchain baseline
and avoids the double textural expansion.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Anthony PERARD <anthony.perard@vates.tech>
CC: Michal Orzel <michal.orzel@amd.com>
CC: Jan Beulich <jbeulich@suse.com>
CC: Julien Grall <julien@xen.org>
CC: Roger Pau Monné <roger.pau@citrix.com>
CC: Stefano Stabellini <sstabellini@kernel.org>
CC: Roberto Bagnara <roberto.bagnara@bugseng.com>
CC: Nicola Vetrini <nicola.vetrini@bugseng.com>
CC: consulting@bugseng.com <consulting@bugseng.com>
The resulting build is identical.
RFC.  This requires a MISRA change, as it currently manifests as a R1.1
violation.  Nevertheless, I think we want to start using in places where we
currently use typeof(expression of <initilaiser>).
Eclair run on this patch (expecting a failure):
  https://gitlab.com/xen-project/hardware/xen-staging/-/pipelines/1800631949
Min toolchain check:
  https://godbolt.org/z/f9WjooPYj
GCC Manual:
  https://www.gnu.org/software/c-intro-and-ref/manual/html_node/Auto-Type.html
---
 xen/include/xen/macros.h | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/xen/include/xen/macros.h b/xen/include/xen/macros.h
index cd528fbdb127..b5e5ff4b1c2f 100644
--- a/xen/include/xen/macros.h
+++ b/xen/include/xen/macros.h
@@ -71,18 +71,18 @@
 /* Hide a value from the optimiser. */
 #define HIDE(x)                                 \
     ({                                          \
-        typeof(x) _x = (x);                     \
+        __auto_type _x = (x);                   \
         asm volatile ( "" : "+r" (_x) );        \
         _x;                                     \
     })
 
 #define ABS(x) ({                              \
-    typeof(x) x_ = (x);                        \
+    __auto_type x_ = (x);                      \
     (x_ < 0) ? -x_ : x_;                       \
 })
 
 #define SWAP(a, b) \
-   do { typeof(a) t_ = (a); (a) = (b); (b) = t_; } while ( 0 )
+   do { __auto_type t_ = (a); (a) = (b); (b) = t_; } while ( 0 )
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]) + __must_be_array(x))
 
@@ -110,15 +110,15 @@
  */
 #define min(x, y)                               \
     ({                                          \
-        const typeof(x) _x = (x);               \
-        const typeof(y) _y = (y);               \
+        const __auto_type _x = (x);             \
+        const __auto_type _y = (y);             \
         (void)(&_x == &_y); /* typecheck */     \
         _x < _y ? _x : _y;                      \
     })
 #define max(x, y)                               \
     ({                                          \
-        const typeof(x) _x = (x);               \
-        const typeof(y) _y = (y);               \
+        const __auto_type _x = (x);             \
+        const __auto_type _y = (y);             \
         (void)(&_x == &_y); /* typecheck */     \
         _x > _y ? _x : _y;                      \
     })
base-commit: 78ce2be733b1e45e2e190c1765fe31da318d435f
-- 
2.39.5
On Mon, 5 May 2025, Andrew Cooper wrote:
> In macros it is common to declare local variables using typeof(param) in order
> to ensure that side effects are only evaluated once.  A consequence of this is
> double textural expansion of the parameter, which can get out of hand very
> quickly with nested macros.
> 
> A GCC extension, __auto_type, is now avaialble in the new toolchain baseline
> and avoids the double textural expansion.
I think this is a good change
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> CC: Anthony PERARD <anthony.perard@vates.tech>
> CC: Michal Orzel <michal.orzel@amd.com>
> CC: Jan Beulich <jbeulich@suse.com>
> CC: Julien Grall <julien@xen.org>
> CC: Roger Pau Monné <roger.pau@citrix.com>
> CC: Stefano Stabellini <sstabellini@kernel.org>
> CC: Roberto Bagnara <roberto.bagnara@bugseng.com>
> CC: Nicola Vetrini <nicola.vetrini@bugseng.com>
> CC: consulting@bugseng.com <consulting@bugseng.com>
> 
> The resulting build is identical.
> 
> RFC.  This requires a MISRA change, as it currently manifests as a R1.1
> violation.  Nevertheless, I think we want to start using in places where we
> currently use typeof(expression of <initilaiser>).
> 
> Eclair run on this patch (expecting a failure):
>   https://gitlab.com/xen-project/hardware/xen-staging/-/pipelines/1800631949
> 
> Min toolchain check:
>   https://godbolt.org/z/f9WjooPYj
> 
> GCC Manual:
>   https://www.gnu.org/software/c-intro-and-ref/manual/html_node/Auto-Type.html
> ---
>  xen/include/xen/macros.h | 14 +++++++-------
>  1 file changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/xen/include/xen/macros.h b/xen/include/xen/macros.h
> index cd528fbdb127..b5e5ff4b1c2f 100644
> --- a/xen/include/xen/macros.h
> +++ b/xen/include/xen/macros.h
> @@ -71,18 +71,18 @@
>  /* Hide a value from the optimiser. */
>  #define HIDE(x)                                 \
>      ({                                          \
> -        typeof(x) _x = (x);                     \
> +        __auto_type _x = (x);                   \
>          asm volatile ( "" : "+r" (_x) );        \
>          _x;                                     \
>      })
>  
>  #define ABS(x) ({                              \
> -    typeof(x) x_ = (x);                        \
> +    __auto_type x_ = (x);                      \
>      (x_ < 0) ? -x_ : x_;                       \
>  })
>  
>  #define SWAP(a, b) \
> -   do { typeof(a) t_ = (a); (a) = (b); (b) = t_; } while ( 0 )
> +   do { __auto_type t_ = (a); (a) = (b); (b) = t_; } while ( 0 )
>  
>  #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]) + __must_be_array(x))
>  
> @@ -110,15 +110,15 @@
>   */
>  #define min(x, y)                               \
>      ({                                          \
> -        const typeof(x) _x = (x);               \
> -        const typeof(y) _y = (y);               \
> +        const __auto_type _x = (x);             \
> +        const __auto_type _y = (y);             \
>          (void)(&_x == &_y); /* typecheck */     \
>          _x < _y ? _x : _y;                      \
>      })
>  #define max(x, y)                               \
>      ({                                          \
> -        const typeof(x) _x = (x);               \
> -        const typeof(y) _y = (y);               \
> +        const __auto_type _x = (x);             \
> +        const __auto_type _y = (y);             \
>          (void)(&_x == &_y); /* typecheck */     \
>          _x > _y ? _x : _y;                      \
>      })
> 
> base-commit: 78ce2be733b1e45e2e190c1765fe31da318d435f
> -- 
> 2.39.5
> 
                
            On 05.05.2025 21:44, Stefano Stabellini wrote: > On Mon, 5 May 2025, Andrew Cooper wrote: >> In macros it is common to declare local variables using typeof(param) in order >> to ensure that side effects are only evaluated once. A consequence of this is >> double textural expansion of the parameter, which can get out of hand very >> quickly with nested macros. >> >> A GCC extension, __auto_type, is now avaialble in the new toolchain baseline >> and avoids the double textural expansion. > > I think this is a good change +1 Jan
On 12/05/2025 12:59 pm, Jan Beulich wrote: > On 05.05.2025 21:44, Stefano Stabellini wrote: >> On Mon, 5 May 2025, Andrew Cooper wrote: >>> In macros it is common to declare local variables using typeof(param) in order >>> to ensure that side effects are only evaluated once. A consequence of this is >>> double textural expansion of the parameter, which can get out of hand very >>> quickly with nested macros. >>> >>> A GCC extension, __auto_type, is now avaialble in the new toolchain baseline >>> and avoids the double textural expansion. >> I think this is a good change > +1 That looks like agreement. Now for the (new) controversial part. Since sending this, Linux has decided to just #define auto __auto_type for C < 23, in order to start writing C23 compatible code from now. It's more succinct, and has better longevity. We might want to consider the same, although it will introduce a new example of defining a keyword, which we'd have to call out in the MISRA/Eclair config. If we're going to do this, we should do it from the outset. Thoughts? ~Andrew
On 12.05.2025 14:09, Andrew Cooper wrote: > On 12/05/2025 12:59 pm, Jan Beulich wrote: >> On 05.05.2025 21:44, Stefano Stabellini wrote: >>> On Mon, 5 May 2025, Andrew Cooper wrote: >>>> In macros it is common to declare local variables using typeof(param) in order >>>> to ensure that side effects are only evaluated once. A consequence of this is >>>> double textural expansion of the parameter, which can get out of hand very >>>> quickly with nested macros. >>>> >>>> A GCC extension, __auto_type, is now avaialble in the new toolchain baseline >>>> and avoids the double textural expansion. >>> I think this is a good change >> +1 > > That looks like agreement. > > Now for the (new) controversial part. Since sending this, Linux has > decided to just #define auto __auto_type for C < 23, in order to start > writing C23 compatible code from now. It's more succinct, and has > better longevity. > > We might want to consider the same, although it will introduce a new > example of defining a keyword, which we'd have to call out in the > MISRA/Eclair config. I'm not outright opposed, as I don't think we use "auto" with its original semantics, but it feels somewhat odd. Jan
On Mon, May 12, 2025 at 03:00:18PM +0200, Jan Beulich wrote: > On 12.05.2025 14:09, Andrew Cooper wrote: > > > > Now for the (new) controversial part. Since sending this, Linux has > > decided to just #define auto __auto_type for C < 23, in order to start > > writing C23 compatible code from now. It's more succinct, and has > > better longevity. > > > > We might want to consider the same, although it will introduce a new > > example of defining a keyword, which we'd have to call out in the > > MISRA/Eclair config. > > I'm not outright opposed, as I don't think we use "auto" with its > original semantics, but it feels somewhat odd. Problem is "auto" already has a defined meaning in C. Having this will subtly break contributions from authors who weren't familiar with everything in Xen's headers. For anyone who does anything with projects besides Xen this will encourage bad habits. I believe many projects have a rule of *never* #define C keywords. I'm surprised such made it into the Linux kernel. I expect it will be ripped out in the near future. MISRA *doesn't* absolutely forbid this? -- (\___(\___(\______ --=> 8-) EHM <=-- ______/)___/)___/) \BS ( | ehem+sigmsg@m5p.com PGP 87145445 | ) / \_CS\ | _____ -O #include <stddisclaimer.h> O- _____ | / _/ 8A19\___\_|_/58D2 7E3D DDF4 7BA6 <-PGP-> 41D1 B375 37D0 8714\_|_/___/5445
On 5/12/25 2:25 PM, Elliott Mitchell wrote: > On Mon, May 12, 2025 at 03:00:18PM +0200, Jan Beulich wrote: >> On 12.05.2025 14:09, Andrew Cooper wrote: >>> >>> Now for the (new) controversial part. Since sending this, Linux has >>> decided to just #define auto __auto_type for C < 23, in order to start >>> writing C23 compatible code from now. It's more succinct, and has >>> better longevity. >>> >>> We might want to consider the same, although it will introduce a new >>> example of defining a keyword, which we'd have to call out in the >>> MISRA/Eclair config. >> >> I'm not outright opposed, as I don't think we use "auto" with its >> original semantics, but it feels somewhat odd. > > Problem is "auto" already has a defined meaning in C.Having this will > subtly break contributions from authors who weren't familiar with > everything in Xen's headers. For anyone who does anything with projects > besides Xen this will encourage bad habits. > > I believe many projects have a rule of *never* #define C keywords. I'm > surprised such made it into the Linux kernel. I expect it will be ripped > out in the near future. > > MISRA *doesn't* absolutely forbid this? I'm no expert on the C standard, but my understanding is that "auto" was redundant starting in C89, so it is almost entirely unused. C++11 and later *do* heavily use "auto", and they use it for roughly the same purpose as C23 does, so I suspect that contributors are far more likely to be familiar with the C23 "auto" than they are with the pre-C23 version, -- Sincerely, Demi Marie Obenour (she/her/hers)
On 13/05/2025 12:04 am, Demi Marie Obenour wrote: > On 5/12/25 2:25 PM, Elliott Mitchell wrote: >> On Mon, May 12, 2025 at 03:00:18PM +0200, Jan Beulich wrote: >>> On 12.05.2025 14:09, Andrew Cooper wrote: >>>> Now for the (new) controversial part. Since sending this, Linux has >>>> decided to just #define auto __auto_type for C < 23, in order to start >>>> writing C23 compatible code from now. It's more succinct, and has >>>> better longevity. >>>> >>>> We might want to consider the same, although it will introduce a new >>>> example of defining a keyword, which we'd have to call out in the >>>> MISRA/Eclair config. >>> I'm not outright opposed, as I don't think we use "auto" with its >>> original semantics, but it feels somewhat odd. >> Problem is "auto" already has a defined meaning in C.Having this will >> subtly break contributions from authors who weren't familiar with >> everything in Xen's headers. For anyone who does anything with projects >> besides Xen this will encourage bad habits. >> >> I believe many projects have a rule of *never* #define C keywords. I'm >> surprised such made it into the Linux kernel. I expect it will be ripped >> out in the near future. >> >> MISRA *doesn't* absolutely forbid this? > I'm no expert on the C standard, but my understanding is that "auto" was > redundant starting in C89, so it is almost entirely unused. C++11 and later > *do* heavily use "auto", and they use it for roughly the same purpose as C23 > does, so I suspect that contributors are far more likely to be familiar with > the C23 "auto" than they are with the pre-C23 version, auto in older versions of C is a storage classifier, so grouped with static, extern and register. It is inherited from B, and along with K&R's having implicit int types, was there for familiarity of code to existing programmers. e.g. "auto a, b, c;" was B's way of saying "I'd like 3 ints on the stack please". It is very rare to see in C these days. C++11 repurposed 'auto' as a type, and C23 has followed suit. This is compatible with the prior meaning, and 'auto' can still be used as a storage classifier in C23. You can't however use 'auto auto'. In GCC/Clang prior to C23, the same behaviour is available from __auto_type. So. auto as a type inference keyword will be commonplace C in few years, just like it is already commonplace C++ for a decade. Right now in Xen, we can choose to either use something that is on the brink of becoming normal, or we can use the older form which will get changed at some point in the future. One of these makes far more sense than the other, considering that it is already standardised C23. ~Andrew
On 2025-05-12 20:25, Elliott Mitchell wrote: > On Mon, May 12, 2025 at 03:00:18PM +0200, Jan Beulich wrote: >> On 12.05.2025 14:09, Andrew Cooper wrote: >> > >> > Now for the (new) controversial part. Since sending this, Linux has >> > decided to just #define auto __auto_type for C < 23, in order to start >> > writing C23 compatible code from now. It's more succinct, and has >> > better longevity. >> > >> > We might want to consider the same, although it will introduce a new >> > example of defining a keyword, which we'd have to call out in the >> > MISRA/Eclair config. >> >> I'm not outright opposed, as I don't think we use "auto" with its >> original semantics, but it feels somewhat odd. > > Problem is "auto" already has a defined meaning in C. Having this will > subtly break contributions from authors who weren't familiar with > everything in Xen's headers. For anyone who does anything with > projects > besides Xen this will encourage bad habits. > > I believe many projects have a rule of *never* #define C keywords. I'm > surprised such made it into the Linux kernel. I expect it will be > ripped > out in the near future. > > MISRA *doesn't* absolutely forbid this? It does, and in fact I don't think that is a wise decision (it's not quite UB I think because Xen does not use standard library headers, but still). However Xen does already #define "inline" with a specific rationale. I could find only [1] as a reference to the discussion in Linux, but perhaps I missed something. Do you have more recent thread @Andrew? [1] https://lore.kernel.org/lkml/d4f87590-6cbb-4ee9-bead-7d958fc1fa83@p183/#R -- Nicola Vetrini, B.Sc. Software Engineer BUGSENG (https://bugseng.com) LinkedIn: https://www.linkedin.com/in/nicola-vetrini-a42471253
On Mon, May 12, 2025 at 1:09 PM Andrew Cooper <andrew.cooper3@citrix.com> wrote: > > On 12/05/2025 12:59 pm, Jan Beulich wrote: > > On 05.05.2025 21:44, Stefano Stabellini wrote: > >> On Mon, 5 May 2025, Andrew Cooper wrote: > >>> In macros it is common to declare local variables using typeof(param) in order > >>> to ensure that side effects are only evaluated once. A consequence of this is > >>> double textural expansion of the parameter, which can get out of hand very > >>> quickly with nested macros. > >>> > >>> A GCC extension, __auto_type, is now avaialble in the new toolchain baseline > >>> and avoids the double textural expansion. > >> I think this is a good change > > +1 > > That looks like agreement. > > Now for the (new) controversial part. Since sending this, Linux has > decided to just #define auto __auto_type for C < 23, in order to start > writing C23 compatible code from now. It's more succinct, and has > better longevity. > > We might want to consider the same, although it will introduce a new > example of defining a keyword, which we'd have to call out in the > MISRA/Eclair config. > > If we're going to do this, we should do it from the outset. > > Thoughts? > > ~Andrew > I vote for avoiding extensions when the same feature is implemented by standard, so yes for using "auto". Frediano
On 2025-05-05 14:46, Andrew Cooper wrote:
> In macros it is common to declare local variables using typeof(param) 
> in order
> to ensure that side effects are only evaluated once.  A consequence of 
> this is
> double textural expansion of the parameter, which can get out of hand 
> very
> quickly with nested macros.
> 
> A GCC extension, __auto_type, is now avaialble in the new toolchain 
> baseline
> and avoids the double textural expansion.
> 
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> CC: Anthony PERARD <anthony.perard@vates.tech>
> CC: Michal Orzel <michal.orzel@amd.com>
> CC: Jan Beulich <jbeulich@suse.com>
> CC: Julien Grall <julien@xen.org>
> CC: Roger Pau Monné <roger.pau@citrix.com>
> CC: Stefano Stabellini <sstabellini@kernel.org>
> CC: Roberto Bagnara <roberto.bagnara@bugseng.com>
> CC: Nicola Vetrini <nicola.vetrini@bugseng.com>
> CC: consulting@bugseng.com <consulting@bugseng.com>
> 
> The resulting build is identical.
> 
> RFC.  This requires a MISRA change, as it currently manifests as a R1.1
> violation.  Nevertheless, I think we want to start using in places 
> where we
> currently use typeof(expression of <initilaiser>).
> 
> Eclair run on this patch (expecting a failure):
>   
> https://gitlab.com/xen-project/hardware/xen-staging/-/pipelines/1800631949
> 
Hi,
to make the analysis pass you need a couple of hunks in 
eclair_analysis/ECLAIR/toolchain.ecl:
-name_selector+={auto_type, "^__auto_type$"}
and add auto_type to the STD.tokenext config below around line 25, then 
later
-name_selector+={ext_auto_type, "^ext_auto_type$"}
and add "ext_auto_type" to the -config lines below
around line 125, along with a reference to the gcc docs above the 
configurations and in C-language-toolchain.rst
This is an extension, so it's usable without further MISRA impact.
> Min toolchain check:
>   https://godbolt.org/z/f9WjooPYj
> 
> GCC Manual:
>   
> https://www.gnu.org/software/c-intro-and-ref/manual/html_node/Auto-Type.html
> ---
>  xen/include/xen/macros.h | 14 +++++++-------
>  1 file changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/xen/include/xen/macros.h b/xen/include/xen/macros.h
> index cd528fbdb127..b5e5ff4b1c2f 100644
> --- a/xen/include/xen/macros.h
> +++ b/xen/include/xen/macros.h
> @@ -71,18 +71,18 @@
>  /* Hide a value from the optimiser. */
>  #define HIDE(x)                                 \
>      ({                                          \
> -        typeof(x) _x = (x);                     \
> +        __auto_type _x = (x);                   \
>          asm volatile ( "" : "+r" (_x) );        \
>          _x;                                     \
>      })
> 
>  #define ABS(x) ({                              \
> -    typeof(x) x_ = (x);                        \
> +    __auto_type x_ = (x);                      \
>      (x_ < 0) ? -x_ : x_;                       \
>  })
> 
>  #define SWAP(a, b) \
> -   do { typeof(a) t_ = (a); (a) = (b); (b) = t_; } while ( 0 )
> +   do { __auto_type t_ = (a); (a) = (b); (b) = t_; } while ( 0 )
> 
>  #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]) + 
> __must_be_array(x))
> 
> @@ -110,15 +110,15 @@
>   */
>  #define min(x, y)                               \
>      ({                                          \
> -        const typeof(x) _x = (x);               \
> -        const typeof(y) _y = (y);               \
> +        const __auto_type _x = (x);             \
> +        const __auto_type _y = (y);             \
>          (void)(&_x == &_y); /* typecheck */     \
>          _x < _y ? _x : _y;                      \
>      })
>  #define max(x, y)                               \
>      ({                                          \
> -        const typeof(x) _x = (x);               \
> -        const typeof(y) _y = (y);               \
> +        const __auto_type _x = (x);             \
> +        const __auto_type _y = (y);             \
>          (void)(&_x == &_y); /* typecheck */     \
>          _x > _y ? _x : _y;                      \
>      })
> 
> base-commit: 78ce2be733b1e45e2e190c1765fe31da318d435f
-- 
Nicola Vetrini, B.Sc.
Software Engineer
BUGSENG (https://bugseng.com)
LinkedIn: https://www.linkedin.com/in/nicola-vetrini-a42471253
                
            On 05/05/2025 1:57 pm, Nicola Vetrini wrote:
> On 2025-05-05 14:46, Andrew Cooper wrote:
>> In macros it is common to declare local variables using typeof(param)
>> in order
>> to ensure that side effects are only evaluated once.  A consequence
>> of this is
>> double textural expansion of the parameter, which can get out of hand
>> very
>> quickly with nested macros.
>>
>> A GCC extension, __auto_type, is now avaialble in the new toolchain
>> baseline
>> and avoids the double textural expansion.
>>
>> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
>> ---
>> CC: Anthony PERARD <anthony.perard@vates.tech>
>> CC: Michal Orzel <michal.orzel@amd.com>
>> CC: Jan Beulich <jbeulich@suse.com>
>> CC: Julien Grall <julien@xen.org>
>> CC: Roger Pau Monné <roger.pau@citrix.com>
>> CC: Stefano Stabellini <sstabellini@kernel.org>
>> CC: Roberto Bagnara <roberto.bagnara@bugseng.com>
>> CC: Nicola Vetrini <nicola.vetrini@bugseng.com>
>> CC: consulting@bugseng.com <consulting@bugseng.com>
>>
>> The resulting build is identical.
>>
>> RFC.  This requires a MISRA change, as it currently manifests as a R1.1
>> violation.  Nevertheless, I think we want to start using in places
>> where we
>> currently use typeof(expression of <initilaiser>).
>>
>> Eclair run on this patch (expecting a failure):
>>  
>> https://gitlab.com/xen-project/hardware/xen-staging/-/pipelines/1800631949
>>
>
> Hi,
>
> to make the analysis pass you need a couple of hunks in
> eclair_analysis/ECLAIR/toolchain.ecl:
>
> -name_selector+={auto_type, "^__auto_type$"}
>
> and add auto_type to the STD.tokenext config below around line 25,
> then later
>
> -name_selector+={ext_auto_type, "^ext_auto_type$"}
>
> and add "ext_auto_type" to the -config lines below
>
> around line 125, along with a reference to the gcc docs above the
> configurations and in C-language-toolchain.rst
>
> This is an extension, so it's usable without further MISRA impact.
Excellent, thankyou.
I'll leave this email out for discussion, and if it goes in a positive
direction, I'll submit a v2 with (hopefully) all the MISRA/Eclair
changes required.
~Andrew
                
            © 2016 - 2025 Red Hat, Inc.