> One of those functions needs a 2nd arg, which means that to keep
> compatible function profiles these days, I need to add the extra arg
> to all of them

Or complicate the call sites, yes.

> In the ancient past I would have just added an extra arg to the one
> that needs it, and the call site, and all the other functions would
> just have continued using the one arg that they have used before (all
> they need) and the function which needs the extra arg would declare
> that, and use it, and all would have been good.

> However, I don't believe that works any more,

It _works_, in that it behaves that way.  Usually.  Depending on the
processor, the compiler, the ABI in use, the optimization level, and in
corner cases probably the phase of the moon and what you had for lunch
a week ago.

> Sigh - C used to be such a nice flexible language...

It still is.  Most compilers will let you play fast and loose with
function calling sequences as you sketch...on processors and compilers
where it works.  C is actually an interesting case, in that it has
become a major force towards portability.  Time was, you _expected_ to
have to fiddle the code in order to move software from (say) a VAX to a
68020.  It's only since C's dominance really took hold that there's
been much expectation that moving code between disparate environments
consists of nothing more than "make".

> I could add something stupid like
>       arg = arg;
> or something to use the value (but then the compiler is likely to
> warn about arg being assigned a value which is never used) - but even
> if that would work, is at least potentially meaningless extra code
> generated.

I have seen two common ways of dealing with this.

One is

        (void)arg;

which does nothing formally, but compilers that warn about unused args
usually take it as a use of the arg.  (It also has a use in forcing a
read of a volatile object, but that's not relevant here.)

The other is __attribute__((__unused__)), which I think was invented by
gcc and I've recently seen some small reason to think it's been copied
by at least one other compiler.

In...C++, I think it is?, you can do this by declaring the unused arg
without a name, as in

void fxn(int arg1, int)
{
 ...
}

but as far as I know nobody's picked that up in C.  (It strikes me as a
very sensible approach.)

For your use case, something NetBSD-specific like the __USE or __unused
mentioned upthread might be best.  I'm not sure what I think of that.
It improves theoretical portability (as in, to port to something
unexpected you just need to provide a suitable __USE or __unused
definition), at the cost of impairing practical portability (I suspect
use of compilers that handle (void)arg or __attribute__ is commoner
than the presence of __USE or whatever).

/~\ The ASCII                             Mouse
\ / Ribbon Campaign
 X  Against HTML                mo...@rodents-montreal.org
/ \ Email!           7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B

Reply via email to