Message ID | 20211005152611.4120605-1-keescook@chromium.org (mailing list archive) |
---|---|
State | Not Applicable, archived |
Headers | show |
Series | [v5] docs: Explain the desired position of function attributes | expand |
On Tue, 2021-10-05 at 08:26 -0700, Kees Cook wrote: > While discussing how to format the addition of various function > attributes, some "unwritten rules" of ordering surfaced[1]. Capture as > close as possible to Linus's preferences for future reference. > +For example, using this function declaration example:: > + > + __init void * __must_check action(enum magic value, size_t size, u8 count, > + char *fmt, ...) __printf(4, 5) __malloc; trivia: almost all fmt declarations should be const char * > +Note that for a function **definition** (i.e. the actual function body), > +the compiler does not allow function parameter attributes after the > +function parameters. In these cases, they should go after the storage > +class attributes (e.g. note the changed position of ``__printf(4, 5)`` > +below, compared to the **declaration** example above):: > + > + static __always_inline __init __printf(4, 5) void * __must_check action(enum magic value, > + size_t size, u8 count, char *fmt, ...) __malloc here too, and 80 columns? > + { > + ... > + } Or just put all the attributes before the storage class... <grumble/chuckle> cheers, Joe
On Tue, Oct 05, 2021 at 08:39:14AM -0700, Joe Perches wrote: > On Tue, 2021-10-05 at 08:26 -0700, Kees Cook wrote: > > While discussing how to format the addition of various function > > attributes, some "unwritten rules" of ordering surfaced[1]. Capture as > > close as possible to Linus's preferences for future reference. > > +For example, using this function declaration example:: > > + > > + __init void * __must_check action(enum magic value, size_t size, u8 count, > > + char *fmt, ...) __printf(4, 5) __malloc; > > trivia: almost all fmt declarations should be const char * Heh, good point! > > +Note that for a function **definition** (i.e. the actual function body), > > +the compiler does not allow function parameter attributes after the > > +function parameters. In these cases, they should go after the storage > > +class attributes (e.g. note the changed position of ``__printf(4, 5)`` > > +below, compared to the **declaration** example above):: > > + > > + static __always_inline __init __printf(4, 5) void * __must_check action(enum magic value, > > + size_t size, u8 count, char *fmt, ...) __malloc > > here too, and 80 columns? Kernel standard is now 100. *shrug* > > + { > > + ... > > + } > > Or just put all the attributes before the storage class... <grumble/chuckle> I hear ya...
On 10/5/21 10:04 AM, Kees Cook wrote: > On Tue, Oct 05, 2021 at 08:39:14AM -0700, Joe Perches wrote: >> On Tue, 2021-10-05 at 08:26 -0700, Kees Cook wrote: >>> While discussing how to format the addition of various function >>> attributes, some "unwritten rules" of ordering surfaced[1]. Capture as >>> close as possible to Linus's preferences for future reference. >>> +For example, using this function declaration example:: >>> + >>> + __init void * __must_check action(enum magic value, size_t size, u8 count, >>> + char *fmt, ...) __printf(4, 5) __malloc; >> >> trivia: almost all fmt declarations should be const char * > > Heh, good point! > >>> +Note that for a function **definition** (i.e. the actual function body), >>> +the compiler does not allow function parameter attributes after the >>> +function parameters. In these cases, they should go after the storage >>> +class attributes (e.g. note the changed position of ``__printf(4, 5)`` >>> +below, compared to the **declaration** example above):: >>> + >>> + static __always_inline __init __printf(4, 5) void * __must_check action(enum magic value, >>> + size_t size, u8 count, char *fmt, ...) __malloc >> >> here too, and 80 columns? > > Kernel standard is now 100. *shrug* That's more for exceptions, not the common rule. AFAIUI. > >>> + { >>> + ... >>> + } >> >> Or just put all the attributes before the storage class... <grumble/chuckle> > > I hear ya... >
On Tue, 2021-10-05 at 12:15 -0700, Randy Dunlap wrote: > On 10/5/21 10:04 AM, Kees Cook wrote: > > On Tue, Oct 05, 2021 at 08:39:14AM -0700, Joe Perches wrote: > > > On Tue, 2021-10-05 at 08:26 -0700, Kees Cook wrote: > > > > While discussing how to format the addition of various function > > > > attributes, some "unwritten rules" of ordering surfaced[1]. Capture as > > > > close as possible to Linus's preferences for future reference. > > > > +For example, using this function declaration example:: > > > > + > > > > + __init void * __must_check action(enum magic value, size_t size, u8 count, > > > > + char *fmt, ...) __printf(4, 5) __malloc; > > > > > > trivia: almost all fmt declarations should be const char * > > > > Heh, good point! > > > > > > +Note that for a function **definition** (i.e. the actual function body), > > > > +the compiler does not allow function parameter attributes after the > > > > +function parameters. In these cases, they should go after the storage > > > > +class attributes (e.g. note the changed position of ``__printf(4, 5)`` > > > > +below, compared to the **declaration** example above):: > > > > + > > > > + static __always_inline __init __printf(4, 5) void * __must_check action(enum magic value, > > > > + size_t size, u8 count, char *fmt, ...) __malloc > > > > > > here too, and 80 columns? > > > > Kernel standard is now 100. *shrug* > > That's more for exceptions, not the common rule. > AFAIUI. And for function definitions that are not static inline, when separate function declarations exist, the function definition does not need any attribute marking at all.
Kees Cook <keescook@chromium.org> writes: > While discussing how to format the addition of various function > attributes, some "unwritten rules" of ordering surfaced[1]. Capture as > close as possible to Linus's preferences for future reference. > > (Though I note the dissent voiced by Joe Perches, Alexey Dobriyan, and > others that would prefer all attributes live on a separate leading line.) > > [1] https://lore.kernel.org/mm-commits/CAHk-=wiOCLRny5aifWNhr621kYrJwhfURsa0vFPeUEm8mF0ufg@mail.gmail.com/ > > Signed-off-by: Kees Cook <keescook@chromium.org> > --- > v5: > - drop extern (joe) > - fix __malloc position (miguel) > v4: https://lore.kernel.org/lkml/20210930235754.2635912-1-keescook@chromium.org > --- > Documentation/process/coding-style.rst | 37 +++++++++++++++++++++++++- > 1 file changed, 36 insertions(+), 1 deletion(-) I've applied this, thanks. jon
diff --git a/Documentation/process/coding-style.rst b/Documentation/process/coding-style.rst index 42969ab37b34..5756ff775233 100644 --- a/Documentation/process/coding-style.rst +++ b/Documentation/process/coding-style.rst @@ -480,13 +480,48 @@ closing function brace line. E.g.: } EXPORT_SYMBOL(system_is_up); +6.1) Function prototypes +************************ + In function prototypes, include parameter names with their data types. Although this is not required by the C language, it is preferred in Linux because it is a simple way to add valuable information for the reader. -Do not use the ``extern`` keyword with function prototypes as this makes +Do not use the ``extern`` keyword with function declarations as this makes lines longer and isn't strictly necessary. +When writing function prototypes, please keep the `order of elements regular +<https://lore.kernel.org/mm-commits/CAHk-=wiOCLRny5aifWNhr621kYrJwhfURsa0vFPeUEm8mF0ufg@mail.gmail.com/>`_. +For example, using this function declaration example:: + + __init void * __must_check action(enum magic value, size_t size, u8 count, + char *fmt, ...) __printf(4, 5) __malloc; + +The preferred order of elements for a function prototype is: + +- storage class (below, ``static __always_inline``, noting that ``__always_inline`` + is technically an attribute but is treated like ``inline``) +- storage class attributes (here, ``__init`` -- i.e. section declarations, but also + things like ``__cold``) +- return type (here, ``void *``) +- return type attributes (here, ``__must_check``) +- function name (here, ``action``) +- function parameters (here, ``(enum magic value, size_t size, u8 count, char *fmt, ...)``, + noting that parameter names should always be included) +- function parameter attributes (here, ``__printf(4, 5)``) +- function behavior attributes (here, ``__malloc``) + +Note that for a function **definition** (i.e. the actual function body), +the compiler does not allow function parameter attributes after the +function parameters. In these cases, they should go after the storage +class attributes (e.g. note the changed position of ``__printf(4, 5)`` +below, compared to the **declaration** example above):: + + static __always_inline __init __printf(4, 5) void * __must_check action(enum magic value, + size_t size, u8 count, char *fmt, ...) __malloc + { + ... + } 7) Centralized exiting of functions -----------------------------------
While discussing how to format the addition of various function attributes, some "unwritten rules" of ordering surfaced[1]. Capture as close as possible to Linus's preferences for future reference. (Though I note the dissent voiced by Joe Perches, Alexey Dobriyan, and others that would prefer all attributes live on a separate leading line.) [1] https://lore.kernel.org/mm-commits/CAHk-=wiOCLRny5aifWNhr621kYrJwhfURsa0vFPeUEm8mF0ufg@mail.gmail.com/ Signed-off-by: Kees Cook <keescook@chromium.org> --- v5: - drop extern (joe) - fix __malloc position (miguel) v4: https://lore.kernel.org/lkml/20210930235754.2635912-1-keescook@chromium.org --- Documentation/process/coding-style.rst | 37 +++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-)