1. phases of translation
2. constant rescanning and reparsing of .h files
3. cannot parse without doing semantic analysis
4. the preprocessor has its own tokens - so you gotta tokenize the .h file, do the preprocessing, convert it back to text, then tokenize the text again with the C/C++ compiler. This is madness. (Although with the C compiler I did manage to merge the preprocessor lexer with the compiler lexer, this made it the speed champ.)
This experience fed into D which:
1. uses modules instead of .h files. No matter how many times a module is imported, it is lexed/parsed/semanticed exactly once.
2. module semantics are independent of who/what imports them
3. no phases of translation
4. lexing and parsing is independent of semantic analysis