Passing parameter to function not expecting parameter

M

Mister B

I have come across some code that has been working for years, in which
function A calls function B and passes a parameter, but function B
does not expect any parameters!
(Obviously there was no prototype for B, an oversight which is being
corrected. With full warnings on, gcc warns of "implicit declaration"
which was the clue).

Anyway, my question is: what type of problems might this have been
causing?

I know, I know, you'll tell me nasal daemons and anything at all etc
etc, but thnking about some typical implementations, might there be
some data hanging around on a stack or something that could get future
data out of sync, or would anything get cleared on exit from B?

TIA
Mark

(P.S. Apologies if this appears twice, I seemed to crash during 1st
posting)
 
I

Ike Naar

None. The argument value is made available to the called function. On return,
all arguments are discarded. The same for var-args if you have extra values.

Caveat: there are calling conventions where the caller pushes arguments onto the
call stack, but the callee is responsible for cleanup of the call stack
(see http://en.wikipedia.org/wiki/X86_calling_conventions for examples).
Under those circumstances it could be problematic if caller and callee have
different ideas about the number of arguments.
 
F

Francois Grieu

I have come across some code that has been working for years, in which
function A calls function B and passes a parameter, but function B
does not expect any parameters!
(Obviously there was no prototype for B, an oversight which is being
corrected. With full warnings on, gcc warns of "implicit declaration"
which was the clue).

Anyway, my question is: what type of problems might this have been
causing?

I know, I know, you'll tell me nasal daemons and anything at all etc
etc, but thnking about some typical implementations, might there be
some data hanging around on a stack or something that could get future
data out of sync, or would anything get cleared on exit from B?

In my experience, in this situation, there is typically no adverse
effect, if (but not only if) all the following applies:
1) both the calling(s) and called function are plain C source (<OT>
rather than assembly or with nonstandard attributes, or in some DLL</OT>);
2) the type of the result of the called function is void or some integer
type of size at most equal to the size of int;
3) the called function does not use the non-supplied argument (you might
often get along with using a non-supplied argument in a harmless way,
especially if it is of some integer type, and perhaps if there are not
too many arguments or the call tree allways includes enough stuff that
there is something more or less defined where the argument should live);
4) the called function has a fixed number of arguments (contrast printf);
5) the function call is explicit (contrast use thru a pointer like for
the comparison function in qsort).

Francois Grieu
 
F

Francois Grieu

[reposted with correction]
I have come across some code that has been working for years, in which
function A calls function B and passes a parameter, but function B
does not expect any parameters!
(Obviously there was no prototype for B, an oversight which is being
corrected. With full warnings on, gcc warns of "implicit declaration"
which was the clue).

Anyway, my question is: what type of problems might this have been
causing?

I know, I know, you'll tell me nasal daemons and anything at all etc
etc, but thnking about some typical implementations, might there be
some data hanging around on a stack or something that could get future
data out of sync, or would anything get cleared on exit from B?

In my experience, in this situation, there is typically no adverse
effect, if (but not only if) all the following applies:
1) both the calling(s) and called function are plain C source (<OT>
rather than assembly or with nonstandard attributes supplied in the
prototype, or/and in some DLL</OT>);
2) the type of the result of the called function is void or some integer
type of size at most equal to the size of int;
3) the function call is explicit (contrast use thru a pointer like for
the comparison function in qsort).

Francois Grieu
 
S

Seebs

I know, I know, you'll tell me nasal daemons and anything at all etc
etc, but thnking about some typical implementations, might there be
some data hanging around on a stack or something that could get future
data out of sync, or would anything get cleared on exit from B?

Depends on the ABI. Usually, if you don't see obvious problems, then
it's harmless. As I understand it, the typical failure modes are pretty
obvious. Usually it just means that the extra arguments from A are
put somewhere that B will then overwrite them without knowing it is doing
so... but so what? They were extra arguments that you didn't care about.

-s
 
A

Andrey Tarasevich

Mister said:
Anyway, my question is: what type of problems might this have been
causing?

From the language point of view, the behavior is undefined.

What will happen in practice is not predictable in general case. It
depends on the implementation.
 
N

Nobody

Caveat: there are calling conventions where the caller pushes arguments
onto the call stack, but the callee is responsible for cleanup of the
call stack (see http://en.wikipedia.org/wiki/X86_calling_conventions for
examples).

Most notably, the "stdcall" convention normally used for Windows DLLs
(with the exception of variadic functions).
Under those circumstances it could be problematic if caller and callee have
different ideas about the number of arguments.

Fortunately, Windows records the size of the argument list for "stdcall"
functions, so you get a link error if the caller passes more or less data
than the callee is expecting.
 
E

Eric Sosman

I have come across some code that has been working for years, in which
function A calls function B and passes a parameter, but function B
does not expect any parameters!
(Obviously there was no prototype for B, an oversight which is being
corrected. With full warnings on, gcc warns of "implicit declaration"
which was the clue).

Anyway, my question is: what type of problems might this have been
causing?

I know, I know, you'll tell me nasal daemons and anything at all etc
etc, but thnking about some typical implementations, might there be
some data hanging around on a stack or something that could get future
data out of sync, or would anything get cleared on exit from B?

Okay, you've already heard the "In principle, anything can
happen" argument, and have decided to discount it. That's fine,
to a point, but keep in mind that even if *every* implementation
*today* acts in a certain way, that doesn't prove that tomorrow's
super-desirable implementation trick will work. "Sorry, sir, but
your code won't work with Frobozz Magic C unless you specify the
-dumbass flag, which causes an eight- to forty-fold slowdown."

But anyhow: Some systems have used (or use today, for all I
know) calling conventions in which the responsibility for stack
(or more generally, "argument") housekeeping is divided between
caller and callee, each side bearing part of the responsibility.
If the caller says "I'm pushing two arguments and I know the called
function will clean them up," while the callee says "I'm receiving
one argument and must dispose of it before returning," you've got
a recipe for disaster: `for (i = 0; i < 100000000; ++i) f(i,x);'
will almost certainly die with a stack overflow, if not worse.

"Bless you, it all depends!" -- Pitti-Sing
 
N

Nick Keighley

In my experience, in this situation, there is typically no adverse
effect, if (but not only if) all the following applies:
1) both the calling(s) and called function are plain C source (<OT>
rather than assembly or with nonstandard attributes, or in some DLL</OT>);
2) the type of the result of the called function is void or some integer
type of size at most equal to the size of int;

this might cause a problem
char *func (int i);

if called without a prototype because the caller assumes func returns
an int and evn if a char* fits in an int the caller may be looking in
the wrong register or something.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top