9

In our C/C++ Project we use a configuration header (~1000 lines) that is full of #ifdef's and #defines

#if (defined(HW_1) || defined(SOME_TECHNOLOGY_SUPPORTED)) && defined(OTHER_TECHNOLOGY_SUPPORTED)
 #define SOME_FEATURE_AVAILABLE
#endif

In our build configuration we predefine some defines that are passed to the compiler. This results in different defines (like SOME_FEATURE_AVEILABLE) in our configuration header.

Since our configuration header is quite big, there is also a bit of a mess.

Are there any alternatives for this #define hell?

Or are there any tools that help to see in what case which defines are set.

We are developing embedded firmware so we can't replace conditional compiling by runtime if's.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
woodtluk
  • 935
  • 8
  • 20
  • 2
    On which system do you compile. For which operating system? Look for `autoconf` and `autotools` .... – Basile Starynkevitch Aug 08 '13 at 10:27
  • 2
    If you stick to ANSI C89 and ISO C++ 98, then you don't need any of them. –  Aug 08 '13 at 10:28
  • Still the compiler may be able to optimise away if conditionals if you define static const booleans. –  Aug 08 '13 at 10:28
  • 4
    I'd look for `cmake`, especially the `configure_file` command. – arne Aug 08 '13 at 10:40
  • 1
    Are you sure that you are not in some cases making premature optimizations when using #define instead of runtime conditionals? –  Aug 08 '13 at 11:12
  • Since your buildsystem basically decides already what's possible and what not, can't you also let your build system take care of including/excluding certain sources? And for the headers: I seriously doubt you need to know if SOME_FEATURE_AVAILABLE is defined everywhere. You could start by splitting up the mega-header into multiple more focused ones. – stijn Aug 08 '13 at 11:19
  • I second the cmake suggestion. With cmake I have the defines already set by the build system also (in some cases) I even have cmake not include cpp and header files that would not be needed if some option is disabled. – drescherjm Aug 08 '13 at 11:46
  • I recommend `cmake`. It has a usefull command to manage defines: http://stackoverflow.com/a/9640357/763394 – hich9n Aug 08 '13 at 16:23
  • Thanks for your answers. We are building with IAR (for target hardware) and Visual Studio (for simulation). I know cmake but we can't use it since it doesn't support generating IAR project files. We need them for debugging on the target hardware. – woodtluk Aug 08 '13 at 18:06
  • @H2CO3: If you can get away with sticking to ANSI C89 (equivalently ISO C90) and ISO C++98, that's great -- but then there are a lot of system-specific things you won't be able to do. For example, all of POSIX would be unavailable. – Keith Thompson Aug 25 '13 at 21:24
  • @KeithThompson unfortunately. But sometimes it'a just inevitable. I generally don't care about Windows and its POSIX-less and C99-lacking stupidity, but my current pet project is written in strict C89 for the sake of maximal portability. –  Aug 26 '13 at 03:05

2 Answers2

1

In case all your #define's are in a single configuration file, you can try doing a preprocessor-only compilation and then finding all defined macros. E.g.,

$ gcc -DFEATURE1 -DFEATURE2 -E configuration.h | grep '#define'
Subhasis Das
  • 1,667
  • 13
  • 13
1

You might want to read about and consider C++ policy-based design (http://en.wikipedia.org/wiki/Policy-based_design) introduced by Alexandrescu in his book "Modern C++ Design".

JohnB
  • 13,315
  • 4
  • 38
  • 65
  • I prefer "bridge" pattern to policy-based design: it achieves the same goal w/out templates or multiple inheritance. – Michael Aug 25 '13 at 17:24
  • I guess bridge incurs some runtime overhead (?). Policy-based design (using templates) does not. Multiple inheriance does not cause problems here, as you do not handle objects as base-class object (do not treat them polymorphically). – JohnB Aug 25 '13 at 17:31