Hacker News new | past | comments | ask | show | jobs | submit login

The fact that I'm calling a function, it must exist, otherwise the compiler will throw an error ("undefined reference to function"). So forward declarations is just needless typing.



> The fact that I'm calling a function, it must exist

That's not necessarily true. It's possible that the symbol is a function pointer; calling a function pointer requires slightly different code generation. Compare the generated code between:

  void fn(void);
  void call_fn(void) { fn(); }
and

  void (*fn_ptr)(void);
  void call_fn_ptr(void) { fn_ptr(); }
In practice, it's probably a function, and that's what the compiler assumes if there's no declaration to go off of. But we all know what happens when you make assumptions.


Making no assumption on safety, just stating that forward declarations are superfluous.


no they are not. but >The fact that I'm calling a function, it must exist, otherwise the compiler will throw an error ("undefined reference to function")

you mean the linker will throw an error. The linker is trying to link together the "references" be they forward or backward, that the compiler has created, and the compiler needs to have generated the right references, round peg round hole, square peg square hole.

You don't want your linker throwing errors, it doesn't have the context the compiler does; and you don't want to turn the linker into ChatGPT that can converse with you about your source code, just use the C version of forward references which are not particularly forward, they just say "I don't know where this is defined, it's just not defined here, but we know it's a square peg"

For example, there are architectures where space is tight (embedded for example) and nearby things can be called more efficiently than far away things, so the compiler needs to generate as many near calls as it can, falling back to far away when it has to. It doesn't know in advance how far away things are going to be, but it might uncover plenty of near things as it goes. Square pegs, round pegs.

when you recompile your project code, the library code, is not necessarily around. When other people recompile their library code, your project code isn't around. What's the size of what's being put on the stack? Still gotta get the square/round pegs right.


I know why it exists. It’s still superfluous to most use cases. Don’t force me. Require it when you can’t figure it out.


"long far pascal", et al, anyone?

Win32 C code from way back.

Heh.


The compiler needs to see it to know how to call it.


In which case, it needs to keep parsing the include tree until it finds it. I know why it exists. I’m just not happy about duplicating code. Other compilers are smarter than this.


If you're using a modern IDE, clangd can be configured to automatically insert #include statements (--header-insertion=iwyu).


The thing I hate about this is that it really has no idea what a “public” header is. If I have it on I’ll use something like uintptr_t and get a random include for <__bits/std/uintptr.h> or something that I don’t want. I assume there’s like some manual auditing one can do to go “don’t peek through stdint.h” but either nobody does this reliably or it doesn’t work.




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

Search: