Alternatives/Tools for #define hell C/C++
Asked Answered
S

2

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.

Serg answered 8/8, 2013 at 10:25 Comment(11)
On which system do you compile. For which operating system? Look for autoconf and autotools ....Whelan
If you stick to ANSI C89 and ISO C++ 98, then you don't need any of them.Hyalite
Still the compiler may be able to optimise away if conditionals if you define static const booleans.Bohemia
I'd look for cmake, especially the configure_file command.Linin
Are you sure that you are not in some cases making premature optimizations when using #define instead of runtime conditionals?Bohemia
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.Okay
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.Evante
I recommend cmake. It has a usefull command to manage defines: https://mcmap.net/q/336140/-cmake-how-to-pass-preprocessor-macrosOraorabel
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.Serg
@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.Genni
@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.Hyalite
D
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'
Despiteful answered 9/8, 2013 at 1:10 Comment(0)
J
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".

Jari answered 25/8, 2013 at 17:5 Comment(2)
I prefer "bridge" pattern to policy-based design: it achieves the same goal w/out templates or multiple inheritance.Whyte
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).Jari

© 2022 - 2024 — McMap. All rights reserved.