The size of integers and other primitive types is not fixed by the C/C++ programming language specifications. It is implementation-defined. Unlike unspecified and undefined behavior, that is not a free lunch for the compiler. Implementation-defined behavior has to be specified in the compiler’s documentation. Once that is done, the language specification kicks in with a great number of detailed requirements for C and C++ arithmetic behavior.
There are rules for implicit and explicit conversion between arithmetic types. There are rules for argument promotion and bit-fields in structures. There are rules for the modulo of negative values and the overflow of unsigned variables.
The big question is: how to write tests to verify the arithmetic of compiler-generated code if we do not know how many bits an integer can hold?
Well, we are not completely empty-handed. For starters, C and C++ define the smallest permitted maximum values for all arithmetic types. For a plain signed int, the standard says that it must have at least 16 bits. We can already do quite a bit of test arithmetic with 16-bit integers. But if you want to write a complete test suite, you have to write them to cover representative values in the complete arithmetic domain. For an integer that has 32 bits, you need to test with values bigger than 32767. And you want your tests to verify the arithmetic with boundary values such as those maximum and minimum values that an int can represent.
Our solution is the collection of arithmetic depth suites that is included in SuperTest. In the latest update, we include 42 in-depth test suites for arithmetic in all kinds of data models, some of which are outlandish (when did you last work with 24-bit characters?) but based on actual implementations. They contain literally millions of test cases that verify every nook and cranny of the target’s arithmetic.
Here is a tip: run the depth suite with and without constant propagation optimizations. It verifies that the arithmetic at compile time is the same as the arithmetic at run-time. This is not a given for cross compilers, especially when it comes to floating point. If your compiler passes the depth suite, you know it can count!
Dr. Marcel Beemster, CTO
Subscribe to our monthly blog!