Add a macro of an upper bound on the formatted length of an integer

There are lots of places where Puzzles formats integers into
fixed-length buffers using sprintf() with a "%d" format.  This isn't
very safe, since C doesn't guarantee any particular maximum size for an
"int".  However, the restrictions on representations of integers means
we can infer an upper bound using sizeof(), CHAR_BIT, and an
approximation to the binary log of 10.
This commit is contained in:
Ben Harris
2023-01-02 16:48:20 +00:00
parent 44b5291b48
commit d246077e78
2 changed files with 14 additions and 0 deletions

View File

@ -4819,6 +4819,17 @@ returns the one which compares greater or less respectively.
These macros may evaluate their arguments multiple times. Avoid side These macros may evaluate their arguments multiple times. Avoid side
effects. effects.
\S{utils-max-digits} \cw{MAX_DIGITS()}
The \cw{MAX_DIGITS()} macro, defined in the main Puzzles header file,
takes a type (or a variable of that type) and expands to an integer
constant representing a reasonable upper bound on the number of
characters that a number of that type could expand to when formatted
as a decimal number using the \c{%u} or \c{%d} format of
\cw{printf()}. This is useful for allocating a fixed-size buffer
that's guaranteed to be big enough to \cw{sprintf()} a value into.
Don't forget to add one for the trailing \cw{'\\0'}!
\S{utils-pi} \cw{PI} \S{utils-pi} \cw{PI}
The main Puzzles header file defines a macro \cw{PI} which expands The main Puzzles header file defines a macro \cw{PI} which expands

View File

@ -18,6 +18,9 @@
#define STR_INT(x) #x #define STR_INT(x) #x
#define STR(x) STR_INT(x) #define STR(x) STR_INT(x)
/* An upper bound on the length of sprintf'ed integers (signed or unsigned). */
#define MAX_DIGITS(x) (sizeof(x) * CHAR_BIT / 3 + 2)
/* NB not perfect because they evaluate arguments multiple times. */ /* NB not perfect because they evaluate arguments multiple times. */
#ifndef max #ifndef max
#define max(x,y) ( (x)>(y) ? (x) : (y) ) #define max(x,y) ( (x)>(y) ? (x) : (y) )