Sujet : Re: question about linker
De : david.brown (at) *nospam* hesbynett.no (David Brown)
Groupes : comp.lang.cDate : 27. Nov 2024, 10:53:43
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <vi6q77$3umr3$1@dont-email.me>
References : 1 2 3 4
User-Agent : Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.11.0
On 26/11/2024 20:42, Thiago Adams wrote:
On 26/11/2024 16:25, Bart wrote:
On 26/11/2024 19:11, Thiago Adams wrote:
On 26/11/2024 15:35, Thiago Adams wrote:
Then adding:
>
int strcmp();
>
int main() {
strcmp("a", "b");
}
>
it works in C99 / C11
>
I think in C23 empty parameter list means no args, while in the previous versions (void) means no args.
>
Considering that in previous versions of C we could call a function without its signature I think the compiler only needs the caller side. (of course I am not considering programmer mistakes)
>
So, I think one extra simplification for small compilers is to ignore function parameters.
>
I don't think so. But you are welcome to look at godbolt.org and see for yourself. Try this for example:
Yes..I realized now I am wrong. Considering function calls uses registers I think the old C model works only when passing everything on stack.
No, it should work for other calling conventions too. Passing everything on the stack has not been common practice for many decades, for most processor architectures.
What you have to consider here is the "default argument promotions". If a function is defined to take a "double", and you call it using an int expression without using a function prototype, the result is UB (in a real and practical sense, not just hypothetically). It doesn't matter if arguments are passed on the stack or registers, or if you have 32-bit or 64-bit or any other size of cpu (I don't know why Bart thinks that matters). It is still a disaster.
If you want to write or generate code that calls a function, you need to know /exactly/ what type the parameters are. And you need to call it with parameters of those types. You can do that by having a function prototype and letting the compiler make the appropriate implicit conversions (assuming they are allowed by the language), or you can manually add any required conversions (such as casts) before the call, or you can rely on the default argument promotions if you know the result will be the correct type.
There is - to my knowledge - never a good reason for omitting a function prototype. Implicit function declaration was IMHO one of the biggest design flaws in pre-standard C, and allowing it to continue in C90 after prototypes were added to the language, was a serious mistake. Compilers should complain loudly if you try to call a function without a prototype declaration. (I believe Bart's compiler treats it as a fatal error - it is a non-conformity of which I approve.) And finally in C23 - some thirty years late - the standard finally requires proper prototypes.
I am not all sure why you are generating code C90 code here. I don't think anyone much cares about using strict C90 other than a couple of people in this newsgroup. (People sometimes do have to limit their C to a subset accepted by an old or limited compiler, but usually they then also want to use extensions or post-C90 features that their compiler supports. And are they going to use your tool?) But presumably you know more about your potential users than I do. However, it seems to me that you should not be considering generating code that would be rejected by at least some C compilers - including all C23 compilers.