Forward Referencing in C
twitter.com
twitter.com
I'm well aware that the practice is for compilers to accept this; it was a standard "feature" of K&R C. However, per Wikipedia, this feature was removed in C99 <https://en.wikipedia.org/wiki/ANSI_C#C99> a fact that I verified by reading the forward to the C99 draft standard ISO/IEC 9899:TC3. So I'm a little surprised that the construct is only treated with a warning in `gcc -std=c99 -ansi -pedantic -Wall`.
Hence why so many just try to use GCC everywhere (nowadays clang as well).
GCC does that for everything short of actual things it can't compile, you have to use -Werror[=…] to make it error out.
Thankfully GCC is going ahead with the change anyway.
I don't quite understand the point, is forward references to undeclared things something to strive after?
In my opinion he wrote wrote of the best c/c++ compilers for DOS. If he says something compiler (c) related, I usually pay attention.
Here the the relevant standard quote:
If the expression that precedes the parenthesized argument list in a function call consists solely of an identifier, and if no declaration is visible for this identifier, the identifier is implicitly declared exactly as if, in the innermost block containing the function call, the declaration
extern int identifier();
appearedCompared to everything else a compiler needs to do this is trivial.
Doing it for types is harder though as far as single-pass compilers are concerned. Both are much easier if the compiler builds a syntax tree (or at least a list of all declarations even if the function bodies are handled at a later pass) ahead of time though.
f() { g(1); }
g(x) double x; { printf("%lf\n", x); }
You have to know the type of g's parameter before you can generate code for f.In this context, it isn’t. The comment you replied to was a response to the statement:
> I've implemented this for calls in a single-pass compiler and it is really simple. You just treat the yet-undeclared call as if it was used correctly and add it to a list of calls to check later.
Single-pass compilation is very pertinent. One tenet of c's design is that it should be compilable in a single pass (which is why it is compilable in a single pass, unlike many other programming languages). This is relevant to us because it allows us to make predictions about the language; in particular, if the addition of some feature would cause c to not be compilable in a single pass, we can predict that the feature will not be added to the language. Notice that I have not made any value judgments. You may disagree about the importance of supporting single-pass compilers, but I am not the person you need to convince of that.
You need to be able to (ideally) treat compilation as a dynamic schedule rather than a static list of passes.
Everything else that can fit AST in RAM can do it relatively easily. Modern C compilers have millions of lines and hundreds of person-years of work in them, so two passes and a lookup table is not a big deal.
It's just not done because the C standard doesn't say it should. Perhaps there is some preprocessor crime that this isn't compatible with, or they just don't want to break that PDP-11 compatibility.