Macro Preprocessors should have gone long ago. Having a separate layer that modifies the code before the compiler sees it greatly increases the cognitive load for the programmer.
Sentinel values such as NULL, -1, and NIL require reaching into the data flow in a manual manner to check for errors. Errors should either be a separate type (exceptions) or a separate return value outside of data.