diff options
| author | Ben Harris <bjh21@bjh21.me.uk> | 2023-01-02 16:48:20 +0000 |
|---|---|---|
| committer | Ben Harris <bjh21@bjh21.me.uk> | 2023-01-02 18:09:27 +0000 |
| commit | d246077e78bb1aeafe8829927db23f281cd03c72 (patch) | |
| tree | 7a5b78b0659c06138c700cc92b86c645e22ecebf | |
| parent | 44b5291b48e77810a096933d0b6f8dae5a17300c (diff) | |
| download | puzzles-d246077e78bb1aeafe8829927db23f281cd03c72.zip puzzles-d246077e78bb1aeafe8829927db23f281cd03c72.tar.gz puzzles-d246077e78bb1aeafe8829927db23f281cd03c72.tar.bz2 puzzles-d246077e78bb1aeafe8829927db23f281cd03c72.tar.xz | |
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.
| -rw-r--r-- | devel.but | 11 | ||||
| -rw-r--r-- | puzzles.h | 3 |
2 files changed, 14 insertions, 0 deletions
@@ -4819,6 +4819,17 @@ returns the one which compares greater or less respectively. These macros may evaluate their arguments multiple times. Avoid side 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} The main Puzzles header file defines a macro \cw{PI} which expands @@ -18,6 +18,9 @@ #define STR_INT(x) #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. */ #ifndef max #define max(x,y) ( (x)>(y) ? (x) : (y) ) |