As the saying goes, ‘a chain is only as strong as its weakest link’, and it’s as true in software development as it is in any other walk of life. A lot happens between source code and your target processor, so making sure your C or C++ toolchain remains strong means rigorously checking all the links in relation to one another. That’s exactly what SuperTest does.

We often speak here about the necessity of verifying and qualifying compilers. But the compiler is just one part of a complex toolchain comprising many different components, all of which are needed to make the target hardware machine code function correctly.

In the standard toolchain ( Source Code > Compiler > Assembler > Linker > Loader > Executable ), source code is processed by the compiler to generate assembly code, which is then translated by the assembler into machine code. The linker merges the machine code with the library to create a single executable, and the loader places the executable into the target hardware, ready for execution.

The important point is it’s all connected

Interestingly, the C and C++ language specifications do not define the assembly code that the compiler must produce. Instead, they define the behavior of the program when it executes on the target hardware after going through the entire toolchain. In practice, the compiler has a lot of freedom in deciding what the generated assembly code looks like. The only requirement is that the assembled and linked executable displays the correct behavior.

That’s why SuperTest verifies the integration of the toolchain as a whole, right down to target execution.

And parts of it are complex

One of the reasons why we often speak of qualifying the compiler is because the compiler is by far the most complex component in the toolchain. The compiler itself is also a pipeline of stages. The front end of the compiler – the parser – reads and verifies the program, and creates a structural representation. The compiler then, optionally, applies a sequence of optimizations to make the code as efficient as possible. The final step – the code generator – creates the assembly output. Because of its pipelined nature, an error in any part of the pipeline automatically propagates to the end. No matter how good the code generator is, it cannot fix an error by the parser.

Qualifying the assembler, linker and loader for free

So when we qualify your compiler, SuperTest inevitably verifies the behavior of your entire toolchain, because it automatically exercises downstream components such as the assembler and linker as part of the implementation. In other words, your toolchain as a whole is qualified for the correct translation of C and C++.

Subscribe to our monthly blog!