Disagree.
I am 100% convinced that the preprocessor is THE reason that hacky ugly C won out over functionally-equivalent but more "pure" languages such as Pascal.
Your opinion, bus sorry, I don't agree with that.
For me, C flexibility with "data-struct" and "data-union" coupled with more powerful "pointer arithmetic" is one of *THE* reason whey C is better than Pascal in this specific cases, as well as Pascal, Modula2 and Oberon are better about making a project modular. With C ... it's rather impossible.
--
Anyway, I'm more interested in being able to debug and test the code, therefore
macro represent a serious problem (especially for team-projects) because
1) specifically because macro have no body and no type (and no namespace)
2) so (especially on the ICE side) the can be easily misused
3) and - worse still - sometimes they expand into very complex code
4) that can be difficult to identify and understand in the preprocessed file
5) also it is easy to make error-prone code in macros
6) and it's impossible to step-in a function-like macro because it's not a true-function
7) so it's impossible to make automated test-cases and automated coverage
In short, I don't like Macro because I cannot debug them, while for sure they can mess up your day, and even if you take the time to fix it, well rationally it's unacceptable that I need to manually care manual testing points with an high probability of being error-prone points instead of safely invoking automating testing tools.