You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The only difference between the two is that one is a "system" pin, and the other is a "bio" pin.
Having such similar APIs, where the parameter type is identical (uint8_t) for subtly different types, makes it easy to have coding errors.
possible ways to improve
C is notoriously difficult to add type-safety, in part because of it's willingness to silently convert enum values into any form of integer large enough to store the value. The only place C retains the enum type is within a struct. This does raise the option of defining, for each enum type where type safety is desired, a corresponding structure whose sole field is the enum. Here's a quick summary of some of the benefits / drawbacks....
Drawbacks
Requires defining each enum value twice. Once in the enum, and once to define the structure that has that enum value as its only field. There is no simple way use macros to define this ... and thus is a potential copy/paste error during defining these values.
Neutral
Can define the structure instances as #define ... which makes it easier for compiler to inline everything.
Can publicly define the enum type without defining its values; the structure instances can be defined as extern const ... which allows hiding the enum type values (preserving namespace outside the compilation unit that defines the constants). Link-time optimization for current generation compilers still optimizes this equivalently.
Benefits
Functions that previously took an enum or integer now must receive a type-safe parameter value. This avoids, at compilation time, an entire class of coding errors.
Example
See definition of bp_debug_should_print(), and how the flags vs. levels were defined to prevent their being swapped in calling this function. In the above example, the extra step of declaring the values using extern const, and then instantiating them only in debug_rtt.c, was not used .... instead just #define'ing the values using typecasts.
Recommended
Define an extern const BIO_STRUCTURE_TYPE bio[] that converts from an integer to the type-safe type.
Most likely, the above changes would be done in the existing src/platform/bpi-rev10.h and similar, which already have #define values for BUFDIR0..BUFDIR7 and BUFIO0..BUFIO7, and which already defines an extern const uint8_t bio2bufiopin[8] and extern const uint8_t bio2bufdirpin[8]. Thus, the defines for these (and the extern instances) are already in existence, which should simplify the change.
The text was updated successfully, but these errors were encountered:
henrygab
changed the title
Enable additional type-safety for similar functions
Enable compile-time checks (parameter type-safety) for similar functions
Dec 28, 2024
There are two APIs which both take a pin:
The only difference between the two is that one is a "system" pin, and the other is a "bio" pin.
Having such similar APIs, where the parameter type is identical (
uint8_t
) for subtly different types, makes it easy to have coding errors.possible ways to improve
C is notoriously difficult to add type-safety, in part because of it's willingness to silently convert
enum
values into any form of integer large enough to store the value. The only place C retains theenum
type is within astruct
. This does raise the option of defining, for eachenum
type where type safety is desired, a corresponding structure whose sole field is theenum
. Here's a quick summary of some of the benefits / drawbacks....Drawbacks
enum
value twice. Once in theenum
, and once to define the structure that has thatenum
value as its only field. There is no simple way use macros to define this ... and thus is a potential copy/paste error during defining these values.Neutral
#define
... which makes it easier for compiler to inline everything.enum
type without defining its values; the structure instances can be defined asextern const
... which allows hiding theenum
type values (preserving namespace outside the compilation unit that defines the constants). Link-time optimization for current generation compilers still optimizes this equivalently.Benefits
enum
or integer now must receive a type-safe parameter value. This avoids, at compilation time, an entire class of coding errors.Example
See definition of
bp_debug_should_print()
, and how the flags vs. levels were defined to prevent their being swapped in calling this function. In the above example, the extra step of declaring the values usingextern const
, and then instantiating them only indebug_rtt.c
, was not used .... instead just#define
'ing the values using typecasts.Recommended
Define an
extern const BIO_STRUCTURE_TYPE bio[]
that converts from an integer to the type-safe type.Most likely, the above changes would be done in the existing
src/platform/bpi-rev10.h
and similar, which already have#define
values forBUFDIR0
..BUFDIR7
andBUFIO0
..BUFIO7
, and which already defines anextern const uint8_t bio2bufiopin[8]
andextern const uint8_t bio2bufdirpin[8]
. Thus, the defines for these (and the extern instances) are already in existence, which should simplify the change.The text was updated successfully, but these errors were encountered: