I'm not looking to deny that straight text-substitution has it's drawbacks, you're completely right. But that being said, I still don't see it as big of a deal as it seems. Generally speaking, bad/malicious pre-processor abuse like this sticks out like a sore thumb when you're reviewing code. If you don't have anybody reviewing the code then it doesn't really matter how you disguised it. At least with the C preprocessor, if there's something you're unsure about, you can run the preprocessor separately and look at the output, clearing up all doubt over what it does.
Also worth noting, one of the nicer things about the design of the C preprocessor is that it can be applied to a lot of different file-types. In more complicated low-level C projects, you can run the preprocessor over your C code, assembly code, linker scripts, etc.. which is a huge gain since you can have access to all your constants and simple macros, simplifying work and duplication. You can't get that with something tied to the language - Which is unfortunate, because like you said it's better to avoid the preprocessor, since writing things on the language-level makes them much easier to reason about.)