Interoperability Requires Temperance
After testing the CScout refactoring browser on the FreeBSD kernel, I decided to try it on Linux. I'm getting there, but slowly, and the reason is the gratuitous use of gcc extensions made in the Linux kernel source code. Every time I come across a program construct that CScout doesn't grok, I have to study the C standards to see if the construct is legal C that CScout fails to implement or a gcc extension. Extensions are trouble, because, they're typically only vaguely documented.
The two editions of the C standard provide almost 100% of the details needed to implement a conforming processor of C programs. In contrast gcc and other compilers typically document their extensions from the users' side ("this is how you can use our new cool feature"), and rarely provide enough details for developing a fully compatible implementation. Thus we have open source software limiting interoperability by embracing and extending existing standards. I know one can study the source code to find out the answers, but even with source code available you need to know what questions to ask.
Consider as an example the implementation of C preprocessor predicates. These allow you to write things like:
#assert cross_hosted(sparc64)
#assert target_cpu(i386)
#assert target_cpu(x86)
#if #cross_hosted && #target_cpu(arm 32)
/*
* Code that will get compiled if any cross_hosted predicate
* exists or if the target_cpu predicate is true for the value
* arm 32
*/
#endif
/* Clear all entries of the target_cpu predicate */
#unassert target_cpu
/* Clear a single entry of the cross_hosted predicate */
#unassert cross_hosted(sparc64)
Missing from the documentation of these compilers are details like:
- Is macro expansion performed before or after the evaluation of predicates?
- To what value does a true or false predicate evaluate?
- What is a predicate's namespace and scope?
- Macro expansion is performed after the evaluation of predicates.
- True and false predicates evaluate to 1 and 0, respectively.
- A predicate's namespace is separate and its scope is a compilation unit.