4

I am working on a big, old but actively developed C/C++ code base, where using #define's to control compile-time aspects of code is a common practice. For example, it is common to define -DTARGET_HAS_FEATURE in a Makefile, and then use it in code:

#ifdef TARGET_HAS_FEATURE
// ... conditionally included code
#endif

The project is multi-target and cross-platform, so certain quirks are understandably easier to handle by a smart usage of preprocessor. However I have a strong feeling that at the current stage such macrodefinitions are being overused, and I want to keep them under control. They are essentially seen as global untyped variables conveniently at their disposal by some developers. Needless to say, this enormously complicates understanding what the code actually does, and sometimes hides bugs.

The question here is: are there any approaches to analyzing the environment the preprocessor operates on at the scope of the project, and reporting if certain properties do not hold? An answer might be essentially a static code analyzer tool designed for the preprocessor language, but it can be a flag of existing preprocessor software, a code style guideline, or any other technique meant to address known weak properties of the macrolanguage in existing code base.

Among the properties that I would like to check are:

  1. Whether there are declared defines which are never used in a single place in the code (unused variables).
  2. Whether there are #ifdef-#endif blocks which reference a name never defined in any file (undefined variables).
  3. Whether a same macrodefinition is used both in def/undef and arithmetical expressions (type violation).
  4. Whether a macrodefinition is redefined (changing a constant variable)
  5. Whether the level of nesting #ifdef-#endif expressions is too big (code readability problem).
Grigory Rechistov
  • 2,104
  • 16
  • 25
  • 2
    At a previous workplace, we implemented this kind of thing but it utilized a simple preprocessor step as part of our project's "bootstrap" code, which took a configuration file listing all available feature toggles and their state, then generated a standardized header. The benefit of this is that features could be managed centrally, and it was not possible to use features that had no definition, due to coding standards requiring the use of `#if` instead of `#ifdef`. – paddy Oct 15 '19 at 08:45
  • That sounds like a really interesting tool, such an analyzer! Really complicated too, since some symbol might be used only if some other symbol(s) are used in the proper ways, deep inside some `#if`s. – unwind Oct 15 '19 at 08:45
  • 1
    Can't you do that with a good static code analysis software.? – Guillaume Petitjean Oct 15 '19 at 08:56
  • 3
    You require to parse also `Makefile` to have the list of possible set defines... – Jarod42 Oct 15 '19 at 09:03
  • 2
    Check the [coan](http://coan2.sourceforge.net/) tool mentioned in my question [Is there a C pre-processor which eliminates `#ifdef` blocks based on values defined/undefined?](https://stackoverflow.com/questions/525283/) – Jonathan Leffler Oct 15 '19 at 09:20
  • Is it request for tool suggestions? – Öö Tiib Oct 15 '19 at 10:11
  • @GuillaumePetitjean I am basically asking about such a tool, but in a form more acceptable for the SO format. – Grigory Rechistov Oct 15 '19 at 10:13
  • @ÖöTiib Partly yes, but there may be alternative approaches to the problem not explicitly reducible to the "use this tool" answer. I am looking for all alternatives that might be known. – Grigory Rechistov Oct 15 '19 at 10:14
  • @unwind I am not far away from writing such a tool. Of course quite limited capabilities are needed in my case, understanding of full preprocessor language semantics would be an overkill. Basically, being too "clever" with preprocessor usage should in fact be reported as an error: only simple constructs should be allowed in real-world scenarios, or at least limited whitelisted occasions of convoluted macros may be allowed for compatibility with existing code base. – Grigory Rechistov Oct 15 '19 at 10:28

0 Answers0