Re: calling convention stdcalll and cdecl call
- From: "Alf P. Steinbach" <alfps@xxxxxxxx>
- Date: Sat, 19 Jul 2008 06:43:41 +0200
* Igor Tandetnik:
"Alf P. Steinbach" <alfps@xxxxxxxx> wrote in message
news:s76dnfnYGKVeUR3VnZ2dnUVZ_h3inZ2d@xxxxxxxxxxxxx
* Igor Tandetnik:"Alf P. Steinbach" <alfps@xxxxxxxx> wrote in messageAre you of the impression that a vararg routine can access its
news:XMudnXxazN5UzR3VnZ2dnUVZ_oWdnZ2d@xxxxxxxxxxxxx
* Igor Tandetnik:Your example uses additional domain-specific information that theWith stdcall, the function is responsible for removing itsI'm sorry, that's incorrect (counter-example below).
parameters from the stack. To do this, it must know how many
parameters there are, and thus cannot take variable number of
parameters.
compiler doesn't have, in general: that the first parameter specifies
the total number of remaining parameters,
arguments without some information about them?
I think I finally understand what you are trying to say. Please correct me if I'm wrong.
OK.
It goes like this.
A variadic function needs some way to know which parameters it is given. It could be a printf-like format string, a counter passed as the first parameter, or perhaps some sentinel value terminating the sequence.
OK.
If the compiler can somehow figure out how the function accesses its parameters (presumably by semantic analysis of its source code), it can figure out how many there are, and pop the stack correctly without any additional information from the caller.
Far-fetched.
This is not going to fly for two reasons. First, in general, the problem of figuring out from source code how many arguments the function is going to access is equivalent to the halting problem. Which, as we all know, is undecidable. Even for a moderately complicated code, I don't think modern compilers are that smart. And you probably won't find too many programmers willing to hand-craft assembly code.
OK.
A more realistic approach would be perhaps to instrument va_start, va_arg and va_end. The implementation could work some housekeeping into them to keep track of how deep up the stack they reached. Supporting things like vprintf would be tricky, but probably solvable.
Or a complete redesign of that library support.
None of this adresses the second problem though: a variadic function doesn't have to use, or even known about, all the parameters it is given. We have already discussed the fact that printf may be legitimately called with more parameters than there are format specifiers in its format string. Consider this example:
int find(int what, ...) {
va_list vl;
va_start(vl, what);
int ret;
for (ret = 0; what != va_arg(vl, int); ++ret) ;
va_end(vl);
return ret;
}
The function looks for a given value in a variadic sequence. The caller is responsible for terminating with a searched-for value, but the value may also appear in the middle. Once the function finds the value, there's no way to know whether or not this is the last argument. It can't correctly pop the stack, unless it's somehow passed additional information.
Right.
Essentially then upon seeing
int __stdcall find( int what, ... );
all the compiler needs to remember is to, in its own way, pass the number of argument bytes, and remember to not adjust stack pointer at call site. This is similar to how it must take some action for a __stdcall member function (COM), or for an RVO optimization. That makes the compiled form compiler-specific.
It could be elaborated on with additional notation like
__declspec( nfrs_rgssz ) int __stdcall find( int what, ... );
(darned if I can remember ordinary syntax for __declspec but something like that), and here the compiler would know that it doesn't need to pass the number of argument bytes because the function infers that from the arguments.
If one wishes such functions to be exportable from DLLs in language-independent manner, then a global convention would have to be pushed by e.g. MS and made part of __stdcall. I see no need for that (the only good thing would slightly improved possibility of dynamic error checking for "..." functions, but "..." functions are to be avoided anyway, so, would mostly be a net cost). But the point is that there's nothing in the __stdcall convention that prevents it.
Cheers,
- Alf
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
.
- Follow-Ups:
- Re: calling convention stdcalll and cdecl call
- From: Igor Tandetnik
- Re: calling convention stdcalll and cdecl call
- References:
- Re: calling convention stdcalll and cdecl call
- From: Igor Tandetnik
- Re: calling convention stdcalll and cdecl call
- From: Alf P. Steinbach
- Re: calling convention stdcalll and cdecl call
- From: Igor Tandetnik
- Re: calling convention stdcalll and cdecl call
- From: Alf P. Steinbach
- Re: calling convention stdcalll and cdecl call
- From: Igor Tandetnik
- Re: calling convention stdcalll and cdecl call
- Prev by Date: Re: calling convention stdcalll and cdecl call
- Next by Date: symbols in static libraries
- Previous by thread: Re: calling convention stdcalll and cdecl call
- Next by thread: Re: calling convention stdcalll and cdecl call
- Index(es):
Relevant Pages
|