Skip to content

Commit 957cedd

Browse files
committed
Fixes mpaland#105: Making all potentially-value-altering conversions explicit, and some additional minor changes:
* Now compiling with the `-Wconversion` warning flag when using clang or gcc. * In all cases noticed by gcc in which an implicit conversion was made which could change the converted value - have changed the conversion to be explicit. * Renamed: `get_sign()` -> `get_sign_bit()` (so as to clarify the return value is either 0 or 1, not -1 or 1). * Added explanatory comment for the `double_components` structure.
1 parent 919ee0a commit 957cedd

File tree

2 files changed

+12
-8
lines changed

2 files changed

+12
-8
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ if (CMAKE_C_COMPILER_ID STREQUAL "MSVC")
9292
target_compile_options(printf PRIVATE /W4)
9393
elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR
9494
CMAKE_C_COMPILER_ID STREQUAL "Clang")
95-
target_compile_options(printf PRIVATE -Wall -Wextra -pedantic)
95+
target_compile_options(printf PRIVATE -Wall -Wextra -pedantic -Wconversion)
9696
endif()
9797

9898
if (BUILD_TESTS)

src/printf/printf.c

+11-7
Original file line numberDiff line numberDiff line change
@@ -261,10 +261,10 @@ static inline double_with_bit_access get_bit_access(double x)
261261
return dwba;
262262
}
263263

264-
static inline int get_sign(double x)
264+
static inline int get_sign_bit(double x)
265265
{
266266
// The sign is stored in the highest bit
267-
return get_bit_access(x).U >> (DOUBLE_SIZE_IN_BITS - 1);
267+
return (int) (get_bit_access(x).U >> (DOUBLE_SIZE_IN_BITS - 1));
268268
}
269269

270270
static inline int get_exp2(double_with_bit_access x)
@@ -358,7 +358,7 @@ static inline output_gadget_t discarding_gadget()
358358
static inline output_gadget_t buffer_gadget(char* buffer, size_t buffer_size)
359359
{
360360
printf_size_t usable_buffer_size = (buffer_size > PRINTF_MAX_POSSIBLE_BUFFER_SIZE) ?
361-
PRINTF_MAX_POSSIBLE_BUFFER_SIZE : buffer_size;
361+
PRINTF_MAX_POSSIBLE_BUFFER_SIZE : (printf_size_t) buffer_size;
362362
output_gadget_t result = discarding_gadget();
363363
if (buffer != NULL) {
364364
result.buffer = buffer;
@@ -539,9 +539,13 @@ static void print_integer(output_gadget_t* output, printf_unsigned_value_t value
539539

540540
#if (PRINTF_SUPPORT_DECIMAL_SPECIFIERS || PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS)
541541

542+
// Stores a fixed-precision representation of a double relative
543+
// to a fixed precision (which cannot be determined by examining this structure)
542544
struct double_components {
543545
int_fast64_t integral;
544546
int_fast64_t fractional;
547+
// ... truncation of the actual fractional part of the double value, scaled
548+
// by the precision value
545549
bool is_negative;
546550
};
547551

@@ -561,10 +565,10 @@ static const double powers_of_10[NUM_DECIMAL_DIGITS_IN_INT64_T] = {
561565
static struct double_components get_components(double number, printf_size_t precision)
562566
{
563567
struct double_components number_;
564-
number_.is_negative = get_sign(number);
568+
number_.is_negative = get_sign_bit(number);
565569
double abs_number = (number_.is_negative) ? -number : number;
566570
number_.integral = (int_fast64_t)abs_number;
567-
double remainder = (abs_number - number_.integral) * powers_of_10[precision];
571+
double remainder = (abs_number - (double) number_.integral) * powers_of_10[precision];
568572
number_.fractional = (int_fast64_t)remainder;
569573

570574
remainder -= (double) number_.fractional;
@@ -654,7 +658,7 @@ static struct double_components get_normalized_components(bool negative, printf_
654658
}
655659
else {
656660
components.fractional = (int_fast64_t) scaled_remainder;
657-
scaled_remainder -= components.fractional;
661+
scaled_remainder -= (double) components.fractional;
658662

659663
components.fractional += (scaled_remainder >= rounding_threshold);
660664
if (scaled_remainder == rounding_threshold) {
@@ -765,7 +769,7 @@ static void print_decimal_number(output_gadget_t* output, double number, printf_
765769
// internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse <[email protected]>
766770
static void print_exponential_number(output_gadget_t* output, double number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char* buf, printf_size_t len)
767771
{
768-
const bool negative = get_sign(number);
772+
const bool negative = get_sign_bit(number);
769773
// This number will decrease gradually (by factors of 10) as we "extract" the exponent out of it
770774
double abs_number = negative ? -number : number;
771775

0 commit comments

Comments
 (0)