4 ms·
Forward Referencing in C
- jepler 3y agoI wish folks would be wary of saying "such and such is legal in C _because an implementation accepts it_". 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 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`.
- parasti 3y ago-ansi translates to -std=c90, so you're effectively cancelling the -std=c99.
- xorvoid 3y agoThere must be other context to the tweet because I’m sure that Walter Bright knows all of that..
- n4r9 3y agoTo be fair, the linked Tweet does not claim it is legal behaviour. Just that it ought to be possible, in principle, in at least some situations.
- classified 3y agoJust declare fwd() with a prototype, and everything's good.
- pjmlp 3y agoFirst they need to learn to distinguish what is ISO C and whateve their compiler accepts, the large majority doesn't. Hence why so many just try to use GCC everywhere (nowadays clang as well).
- eqvinox 3y ago> So I'm a little surprised that the construct is only treated with a warning GCC does that for everything short of actual things it can't compile, you have to use -Werror[=…] to make it error out.
- gpderetta 3y agoRecently GCC moved to make this an hard error by default in >=C99 mode. There was huge push back form some very vocal members of the community against such exoteric, bleeding edge type system non-sense like function prototypes; according to them having to add -pedantic to the gcc command-line to build legacy code is an unreasonable breaking change. The burden should be on beginners to find the correct GCC arguments to enable all the "useless" warning. Thankfully GCC is going ahead with the change anyway.
- unwind 3y agoYeah, perhaps even more when they wrote said implementation. :) Nothing against WalterBright, I just thought it was funny to use your own compiler as a referene like that. I don't quite understand the point, is forward references to undeclared things something to strive after?
- MathMonkeyMan 3y agoIt prevents you from having to topologically sort your definitions, or otherwise declare everything at the top. Since idiomatic C uses header files, though, it doesn't matter too much. Main benefit is that non-public implementation details (e.g. static functions) needn't be declared at the top of the source file.
- taneq 3y agoThere’s no such language as C anyway, strictly speaking. There’s the C standard which defines a family of languages, then there’s the (C compiler version, OS, misc factors) tuples that define actual C-like languages.
- kyberias 3y agoWhat is ANSI C or C99 then?
- MathMonkeyMan 3y agoAccording to the parent post, two families of languages. I disagree, though. Each standard _is_ a language. But which one does your compiler implement?
- taneq 3y agoExactly, it's "a language" but what you say will be interpreted differently depending on which specific version of which specific compiler you happen to be using today.
- jmclnx 3y agoI not think you know who Walter Bright is :) 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.
- phoe-krk 3y ago"Proof that C can do forward referencing", as long as you compile it with the D compiler. This is a trait of an implementation, not of the language itself.
- stefncb 3y agoI assume his point was that there's no technical reason for C to not support it.
- mhh__ 3y agoThe technical reason is that it makes the compiler a lot more complicated.
- badsectoracula 3y agoI'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. Compared 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.
- moonchild 3y agoIt hinders single-pass in just the same fashion as types do. Consider: 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.
- proto_lambda 3y ago(that function definition would be "void g(double x) { ... }" in non-obsolete C)
- 3y ago
- camel-cdr 3y agoIsn't it common knowledge that c89 has implicit function declarations? 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(); appeared
- fanf2 3y agoRight. And in the example, the function definition does not match the implicit definition, so it is undefined behaviour. (The calling conventions may differ.)
- deleted 3y ago[deleted]
- deleted 3y ago[deleted]
- deleted 3y ago[deleted]