Skip to content

Commit

Permalink
Regards issue mpaland#118:
Browse files Browse the repository at this point in the history
* Added comment explaining how we "narrowly escape" undefined behavior with our `NTOA_ABS()` macro.
* Added checks for printing extremal values of the various signed and unsigned integer types, just in case.
  • Loading branch information
eyalroz committed Aug 3, 2021
1 parent 20ae081 commit dc67369
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 1 deletion.
3 changes: 3 additions & 0 deletions printf.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ typedef uint8_t numeric_base_t;
#include <float.h>
#endif

// Note in particular the behavior here on LONG_MIN or LLONG_MIN; it is valid
// and well-defined, but if you're not careful you can easily trigger undefined
// behavior with -LONG_MIN or -LLONG_MIN
#define NTOA_ABS(_x) ( (_x) > 0 ? (NTOA_VALUE_TYPE)(_x) : -((NTOA_VALUE_TYPE)_x) )

// output function type
Expand Down
55 changes: 54 additions & 1 deletion test/test_suite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
#include <string.h>
#include <sstream>
#include <math.h>

#include <limits>

namespace test {
// use functions in own test namespace to avoid stdio conflicts
Expand Down Expand Up @@ -1055,6 +1055,59 @@ TEST_CASE("misc", "[]" ) {
#endif
}

TEST_CASE("extremal signed integer values", "[]" ) {
char buffer[100];
char expected[100];

std::sprintf(expected, "%hhd", std::numeric_limits<char>::max());
PRINTING_CHECK(expected, ==, test::sprintf_, buffer, "%hhd", std::numeric_limits<char>::max());

std::sprintf(expected, "%hd", std::numeric_limits<short int>::max());
PRINTING_CHECK(expected, ==, test::sprintf_, buffer, "%hd", std::numeric_limits<short int>::max());

std::sprintf(expected, "%hd", std::numeric_limits<short int>::max());
PRINTING_CHECK(expected, ==, test::sprintf_, buffer, "%hd", std::numeric_limits<short int>::max());

std::sprintf(expected, "%d", std::numeric_limits<int>::min());
PRINTING_CHECK(expected, ==, test::sprintf_, buffer, "%d", std::numeric_limits<int>::min());

std::sprintf(expected, "%d", std::numeric_limits<int>::max());
PRINTING_CHECK(expected, ==, test::sprintf_, buffer, "%d", std::numeric_limits<int>::max());

std::sprintf(expected, "%ld", std::numeric_limits<long int>::min());
PRINTING_CHECK(expected, ==, test::sprintf_, buffer, "%ld", std::numeric_limits<long int>::min());

std::sprintf(expected, "%ld", std::numeric_limits<long int>::max());
PRINTING_CHECK(expected, ==, test::sprintf_, buffer, "%ld", std::numeric_limits<long int>::max());

std::sprintf(expected, "%lld", std::numeric_limits<long long int>::min());
PRINTING_CHECK(expected, ==, test::sprintf_, buffer, "%lld", std::numeric_limits<long long int>::min());

std::sprintf(expected, "%lld", std::numeric_limits<long long int>::max());
PRINTING_CHECK(expected, ==, test::sprintf_, buffer, "%lld", std::numeric_limits<long long int>::max());
}

TEST_CASE("extremal unsigned integer values", "[]" ) {
char buffer[100];
char expected[100];

std::sprintf(expected, "%hhu", std::numeric_limits<char unsigned>::max());
PRINTING_CHECK(expected, ==, test::sprintf_, buffer, "%hhu", std::numeric_limits<char unsigned>::max());

std::sprintf(expected, "%hu", std::numeric_limits<short unsigned>::max());
PRINTING_CHECK(expected, ==, test::sprintf_, buffer, "%hu", std::numeric_limits<short unsigned>::max());

std::sprintf(expected, "%u", std::numeric_limits<unsigned>::max());
PRINTING_CHECK(expected, ==, test::sprintf_, buffer, "%u", std::numeric_limits<unsigned>::max());

std::sprintf(expected, "%lu", std::numeric_limits<long unsigned>::max());
PRINTING_CHECK(expected, ==, test::sprintf_, buffer, "%lu", std::numeric_limits<long unsigned>::max());

std::sprintf(expected, "%llu", std::numeric_limits<long long unsigned>::max());
PRINTING_CHECK(expected, ==, test::sprintf_, buffer, "%llu", std::numeric_limits<long long unsigned>::max());
}


#ifdef TEST_WITH_NON_STANDARD_FORMAT_STRINGS
DISABLE_WARNING_POP
#endif
Expand Down

0 comments on commit dc67369

Please sign in to comment.