First, the use case for T4 is fundamentally different than language macros. You would't use Lisp macros or C macros for what you'd do with T4. For example, I've seen T4 used to do some elaborate documentation generation.
But back to the point, I partially agree with what you say about C, but I think you misunderstand where the crux of the problem. It's not that they're separate stages -- I believe they are in most Lisp implementations (but I may be wrong), but rather that you can't do macro expansion w/o the context of the full program, i.e., within the context of the build system -- yet the effect is global.
"First, the use case for T4 is fundamentally different than language macros. You would't use Lisp macros or C macros for what you'd do with T4. For example, I've seen T4 used to do some elaborate documentation generation."
I don't think you know anything about the use-cases for Lisp macros. It's a standard practice to use them to generate documents (most CL HTML generating libraries are just sets of macros), configuration information (SQL schemas, XML) for other systems, and programs in other languages (for example, this is how Parenscript compiles Lisp to JavaScript).
"rather that you can't do macro expansion w/o the context of the full program, i.e., within the context of the build system -- yet the effect is global."
* don't think you know anything about the use-cases for Lisp macros. It's a standard practice to use them to generate documents (most CL HTML generating libraries are just sets of macros), configuration information (SQL schemas, XML) for other systems, and programs in other languages (for example, this is how Parenscript compiles Lisp to JavaScript).*
Maybe I don't know the Lisp uses cases for writing conceptual docs, but I must say that this sounds horrible. But clearly each to their own... when all you have is a hammer. I'd much rather use just about any templating system (and there are many) than any language (or preprocessing system) that I've ever encountered.
I don't understand this.
In C, the only way to know the impact of macros on code is to build it (preprocess it). And macros have global effect on the code, so you don't know, when looking at any piece of code in C, what it actually does, unless you look at it preprocessed -- for the most part. This means pulling in the build system, since obviously you don't know what is being pulled from where otherwise.
But back to the point, I partially agree with what you say about C, but I think you misunderstand where the crux of the problem. It's not that they're separate stages -- I believe they are in most Lisp implementations (but I may be wrong), but rather that you can't do macro expansion w/o the context of the full program, i.e., within the context of the build system -- yet the effect is global.