Module Name: src Committed By: riastradh Date: Mon Aug 7 18:01:42 UTC 2023
Modified Files: src/share/misc: style Log Message: style(5): Advise against new struct typedefs and explain why. Proposed on tech-kern: https://mail-index.netbsd.org/tech-kern/2023/07/11/msg028950.html Positive feedback to general concept, negative feedback to specifics and phrasing of the first iteration but no objections to latest iteration after several weeks at: https://mail-index.netbsd.org/tech-kern/2023/07/16/msg028994.html To generate a diff of this commit: cvs rdiff -u -r1.74 -r1.75 src/share/misc/style Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/share/misc/style diff -u src/share/misc/style:1.74 src/share/misc/style:1.75 --- src/share/misc/style:1.74 Fri Apr 21 16:12:53 2023 +++ src/share/misc/style Mon Aug 7 18:01:42 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: style,v 1.74 2023/04/21 16:12:53 rillig Exp $ */ +/* $NetBSD: style,v 1.75 2023/08/07 18:01:42 riastradh Exp $ */ /* * The revision control tag appears first, with a blank line after it. @@ -30,7 +30,7 @@ #include <sys/cdefs.h> __COPYRIGHT("@(#) Copyright (c) 2008\ The NetBSD Foundation, inc. All rights reserved."); -__RCSID("$NetBSD: style,v 1.74 2023/04/21 16:12:53 rillig Exp $"); +__RCSID("$NetBSD: style,v 1.75 2023/08/07 18:01:42 riastradh Exp $"); /* * VERY important single-line comments look like this. @@ -58,6 +58,76 @@ __RCSID("$NetBSD: style,v 1.74 2023/04/2 #define _SYS_SOCKET_H_ /* + * Include other header files only as necessary, mainly for type + * definitions or macros that are necessary to use in this header file. + * + * Avoid relying on transitive inclusions. + * + * Avoid header files dependencies just for struct and union types that + * are used in pointer types, which don't require type defintions. + * Instead, use forward declarations of the struct or union tag. + */ +#include <sys/foobar.h> + +/* + * Forward declarations for struct and union tags that don't need + * definitions go next. + */ +struct dirent; + +/* + * Define public structs and unions, only if they are user-allocated or + * otherwise exposed to users for a good reason; otherwise keep them + * private to .c files or `_impl.h' or `_private.h' files. + * + * Do not create a typedef like `typedef struct example example_t;' or + * `typedef struct example *example_t;'. Use `struct example' or + * `struct example *' in the public API; that way, other header files + * which declare functions or define struct or union types that involve + * only pointers to `struct example' need not pull in unnecessary + * header files. + */ +struct example { + struct data *p; + int x; + char y; +}; + +/* + * Use typedefs judiciously. + * + * Function or function pointer types: + */ +typedef void sighandler_t(int); + +/* + * Aliases for arithmetic types: + */ +typedef uint16_t nlink_t; + +/* + * Types that might be defined differently in some contexts, like + * uint8_t on one port, a pointer to a struct on another port, and an + * in-line struct larger than a pointer on a third port: + */ +typedef uint8_t foo_t; /* Hypothetical leg26 definition */ +typedef struct foo *foo_t; /* Hypothetical i786 definition */ +typedef struct { /* Hypothetical risc72 definition */ + uint32_t p; + uint32_t q; + uint8_t t; +} foo_t; + +/* + * For opaque data structures that are always represented by a pointer + * when stored in other data structures or passed to functions, don't + * use a type `foo_t' with `typedef void *foo_t'. Use `struct foo *' + * with no public definition for `struct foo', so the compiler can + * detect type errors, and other header files can use `struct foo *' + * without creating header file dependencies. + */ + +/* * extern declarations must only appear in header files, not in .c * files, so the same declaration is used by the .c file defining it * and the .c file using it, giving the compiler the opportunity to @@ -71,7 +141,7 @@ __RCSID("$NetBSD: style,v 1.74 2023/04/2 */ extern int frotz; -int frobnicate(const char *); +int frobnicate(const char *, struct dirent *, foobar_t); /* * Contents of #include file go between the #ifndef and the #endif at the end. @@ -195,6 +265,10 @@ enum enumtype { * * It may be useful to use a meaningful prefix for each member name. * E.g, for ``struct softc'' the prefix could be ``sc_''. + * + * Don't create typedef aliases for struct or union types. That way, + * other header files can use pointer types to them without the header + * file defining the typedef. */ struct foo { struct foo *next; /* List of active foo */ @@ -207,11 +281,6 @@ struct foo { }; struct foo *foohead; /* Head of global foo list */ -/* Make the structure name match the typedef. */ -typedef struct BAR { - int level; -} BAR; - /* C99 uintN_t is preferred over u_intN_t. */ uint32_t zero;