Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

No, you emit all the code in one go, then after you've done that you have some residual pieces of data left one the side: the symbol table, and the list of all the calls of (hopefully)-forward-declared functions. At this point you could run the check on that list against the symbol table, no additional codegen or re-reading the source text needed.

Granted, you can call that a second pass although that's not that different from emitting a function's epilogue IMHO.



There is no need for the second phase. You can record the implicit declaration when you encounter it, and if there is a subsequent declaration, you can check that it's consistent or error out immediately.

This is what C compilers already do, in fact, to produce warnings when an implicit declaration doesn't match a later explicit declaration. But this is a best-effort warning only; it doesn't work if there is no declaration because the function is defined in a different translation unit, as I pointed out above.


Usually, the second pass in a compiler does not re-parse source files. Rather, it operates on another data structure, like an AST, intermediate representation, or the list mentioned in the original comment. At least, that’s my understanding of multi-pass compilation.


Well, this "list mentioned in the original comment" is not an AST or an immediate representation of the program in any reasonable sense just as a symbol table is not. Otherwise, setting the exact values of the text/data/bss size fields in the executable file header's at the end of the compilation would count as the second pass as well which IMO it should not.


The difference is that you need to make a complete second iteration (or pass) over the entire list to correctly check all of the callsites after all function type information is collected. The same is not true for symbol table usage in a single-pass C compiler.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: