A core requirement for any programming language intended for one-pass compilation is that all user-defined identifiers, except possibly labels, must be declared before use:
Any language which allows preprocessing such as PL/1, C, or C++, must have at least two passes, one pass for preprocessing and one or more passes for translation.
Some computer hardware (e.g. x86) may have short and long branch instructions: short if the destination is within about 127 bytes, and long otherwise. A one-pass compiler must assume that all jumps are long, whereas a multi-pass compiler can check on jump distance and generate possibly shorter code.
Languages which rely on context for statement identification rather than using reserved or stropped keywords may also cause problems. The following examples are from Fortran 77:
The entire statement must be scanned to determine what sort of statement it is; only then can translation take place. Hence any potentially ambiguous statements must be processed at least twice.
"Single pass, Two pass, and Multi pass Compilers". GeeksforGeeks. 2019-03-13. Retrieved 2023-05-15. https://www.geeksforgeeks.org/single-pass-two-pass-and-multi-pass-compilers/ ↩