[2/3] auto: add "auto" keyword as alias for __auto_type

Message ID 20230516164947.86543-2-adobriyan@gmail.com
State New
Headers
Series [1/3] auto, kbuild: flatten KBUILD_CFLAGS |

Commit Message

Alexey Dobriyan May 16, 2023, 4:49 p.m. UTC
  It has similar semantics to "auto" keyword from a language
which can not be named on this mailing list, in particular:

	{
		int a;
		const auto b = a; // const char b = a;
		b = 1;	// compile error
	}
	{
		char a;
		auto b = a; // char b = a;
		// no integer promotions
		static_assert(sizeof(b) == 1);
	}
	{
		int a;
		const auto p = &a; // int *const p = &a;
		*p = 1;	// works because const is applied only to top-level
	}

It can be used to save on macroexpansion inside macro forests which
use typeof() somewhere deep enough. It is cool regardless.

Use "auto" in your code today!

gcc 5.1 supports __auto_type.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
 Makefile | 1 +
 1 file changed, 1 insertion(+)
  

Comments

Andrew Morton May 16, 2023, 9:39 p.m. UTC | #1
On Tue, 16 May 2023 19:49:46 +0300 Alexey Dobriyan <adobriyan@gmail.com> wrote:

> It has similar semantics to "auto" keyword from a language
> which can not be named on this mailing list, in particular:

Huh, 20 years ago C's auto meant "automatic variable".  ie, stored on
the stack.  It was never needed because that's the default, unless you
used `register', which gave the false impression that you're being
faster.

> 	{
> 		int a;
> 		const auto b = a; // const char b = a;

I assume that should be "const int b = a".

> 		b = 1;	// compile error
> 	}
> 	{
> 		char a;
> 		auto b = a; // char b = a;
> 		// no integer promotions
> 		static_assert(sizeof(b) == 1);
> 	}
> 	{
> 		int a;
> 		const auto p = &a; // int *const p = &a;
> 		*p = 1;	// works because const is applied only to top-level
> 	}
> 
> It can be used to save on macroexpansion inside macro forests which
> use typeof() somewhere deep enough. It is cool regardless.
> 
> Use "auto" in your code today!
> 
> gcc 5.1 supports __auto_type.
> 
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
> ---
>  Makefile | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Makefile b/Makefile
> index 10fcc64fcd1f..d316924a466a 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -570,6 +570,7 @@ KBUILD_CFLAGS += -Werror=return-type
>  KBUILD_CFLAGS += -Werror=strict-prototypes
>  KBUILD_CFLAGS += -Wno-format-security
>  KBUILD_CFLAGS += -Wno-trigraphs
> +KBUILD_CFLAGS += -Dauto=__auto_type
>  
>  KBUILD_CPPFLAGS := -D__KERNEL__
>  KBUILD_RUSTFLAGS := $(rust_common_flags) \

Examples at https://lkml.kernel.org/r/20230516164947.86543-3-adobriyan@gmail.com

It is pretty cool and could get used a lot.  Cc Linus for his thoughts?
  
Linus Torvalds May 16, 2023, 11:18 p.m. UTC | #2
On Tue, May 16, 2023 at 2:39 PM Andrew Morton <akpm@linux-foundation.org> wrote:
>
> It is pretty cool and could get used a lot.  Cc Linus for his thoughts?

I'm not against it, although I'm also not convinced we need / want to
convert existing users of typeof().

The reason we use typeof is that that has always worked in gcc, and
__auto_type is relatively "new" in contrast.

But we require at least gcc-5.1 anyway, so it should be fine.

Note that mindless conversions can be dangerous: using "typeof(x)" in
macros may end up feeling a bit verbose, and "auto" can appear nicer,
but the auto use needs to be *very* careful about integer promotions.

For example, in

  #define WRAPPER(c) do { \
        typeof(c) __c = (c);
        ...

it is very obvious what the type is.

But while using

   #define WRAPPER(c) do { \
        auto __c = (c);

gives you the same result with less redundancy (no need to state 'c'
twice), if you *ever* then happen to make that an integer expression
that is not *just* 'c' - even a trivial one - suddenly 'var' goes from
'char' to 'int' because of the integer expression.

So __auto_type (and I agree that if we use it, we should probably just
wrap it in an 'auto' #define, since the legacy 'auto' keyword is
useless) can result in simpler and more obvious code, but it can also
lead to subtle type issues that are easy to then overlook.

The above is not an argument against 'auto', but it's one reason I'm
not convinced some mindless "convert existing uses of __typeof__" is a
good idea even if it might make some of them more legible.

But I have nothing against people starting to use it in new code.

And no, I don't think we should do that

    KBUILD_CFLAGS += -Dauto=__auto_type

in the Makefile as Alexey suggests.

I think this is a 'compiler_types.h' kind of thing, and goes along
with all the other "simplied syntax" things we do (ie we redefine
'inline', we add "__weak" etc etc etc).

                  Linus
  
Alexey Dobriyan May 17, 2023, 6:20 a.m. UTC | #3
On Tue, May 16, 2023 at 04:18:59PM -0700, Linus Torvalds wrote:
> On Tue, May 16, 2023 at 2:39 PM Andrew Morton <akpm@linux-foundation.org> wrote:
> >
> > It is pretty cool and could get used a lot.  Cc Linus for his thoughts?
> 
> I'm not against it, although I'm also not convinced we need / want to
> convert existing users of typeof().
> 
> The reason we use typeof is that that has always worked in gcc, and
> __auto_type is relatively "new" in contrast.
> 
> But we require at least gcc-5.1 anyway, so it should be fine.
> 
> Note that mindless conversions can be dangerous: using "typeof(x)" in
> macros may end up feeling a bit verbose, and "auto" can appear nicer,
> but the auto use needs to be *very* careful about integer promotions.
> 
> For example, in
> 
>   #define WRAPPER(c) do { \
>         typeof(c) __c = (c);
>         ...
> 
> it is very obvious what the type is.
> 
> But while using
> 
>    #define WRAPPER(c) do { \
>         auto __c = (c);
> 
> gives you the same result with less redundancy (no need to state 'c'
> twice), if you *ever* then happen to make that an integer expression
> that is not *just* 'c' - even a trivial one - suddenly 'var' goes from
> 'char' to 'int' because of the integer expression.
> 
> So __auto_type (and I agree that if we use it, we should probably just
> wrap it in an 'auto' #define, since the legacy 'auto' keyword is
> useless) can result in simpler and more obvious code, but it can also
> lead to subtle type issues that are easy to then overlook.
> 
> The above is not an argument against 'auto', but it's one reason I'm
> not convinced some mindless "convert existing uses of __typeof__" is a
> good idea even if it might make some of them more legible.
> 
> But I have nothing against people starting to use it in new code.
> 
> And no, I don't think we should do that
> 
>     KBUILD_CFLAGS += -Dauto=__auto_type
> 
> in the Makefile as Alexey suggests.
> 
> I think this is a 'compiler_types.h' kind of thing, and goes along
> with all the other "simplied syntax" things we do (ie we redefine
> 'inline', we add "__weak" etc etc etc).

Sure. I thought about where to put it in the filesystem under nice name
but somehow completely forgot about compiler_types.h

I'll probably go through core headers at least and start conversion
myself. Expect version 2 soon.
  

Patch

diff --git a/Makefile b/Makefile
index 10fcc64fcd1f..d316924a466a 100644
--- a/Makefile
+++ b/Makefile
@@ -570,6 +570,7 @@  KBUILD_CFLAGS += -Werror=return-type
 KBUILD_CFLAGS += -Werror=strict-prototypes
 KBUILD_CFLAGS += -Wno-format-security
 KBUILD_CFLAGS += -Wno-trigraphs
+KBUILD_CFLAGS += -Dauto=__auto_type
 
 KBUILD_CPPFLAGS := -D__KERNEL__
 KBUILD_RUSTFLAGS := $(rust_common_flags) \