April 2009 Archives

Argument passing

| No Comments

Continuing my attempts to recycle articles written elsewhere… This stuff was originally from comp.lang.python. Its objective is to define the terms ‘pass-by-value’ and ‘pass-by-reference’ in ways which are:

  • reasonably clear,
  • language-independent, and
  • consistent with widely-held expectations.

With a bit of luck and a following wind, the framework here can be extended to cover other weirder argument passing mechanisms, e.g., Algol’s pass-by-name.

If anything here is particularly controversial then I’ve failed.

Executive summary

Here’s the soundbite version.

  • Pass by value: The callee’s parameters are new variables, initialized as if by assignment from the values of the caller’s argument expressions.

    So, we ought to be able to replace

    function mumble(a, b, c) { stuff in terms of a, b, and c }
    ...
    mumble(1 + 2, xyz, whatever)
    

    with

    ...
    fresh_a = 1 + 2
    fresh_b = xyz
    fresh_c = whatever
    stuff in terms of fresh_a, fresh_b and fresh_c
    

    with no observable difference.

  • Pass by reference: The callee’s parameters are merely new names for the caller’s argument variables — to the extent that this makes sense.

    There’s a caveat there for argument expressions which don’t correspond directly to variables. Anyway, the idea is that you should be able to replace

    function mumble(a, b) { stuff in terms of a and b)
    ...
    mumble(xyz, whatever)
    

    by

    ...
    stuff in terms of xyz and whatever
    

    without observable difference.

mdup

| No Comments

Almost every Unix programmer’s done it:

int kid;

if ((kid = fork()) < 0) fail();
if (!kid) {
  if (dup2(x, 0) < 0 ||
      dup2(y, 1) < 0 ||
      dup2(z, 2) < 0)
    fail();
  close(p); close(q); close(r);
  execlp("/bin/foo", "foo", /* args */, (char *)0);
  fail();
}
/* and so on... */

And it’s wrong. What if y is zero? You’ve clobbered it too early!

This is fairly easy to deal with if you know where you got these file descriptors from. If you just got them by calling pipe(2), then you’ll know that they’re in ascending order, so you can dup2(2) them in the right order and all will be well. If you’re writing a library function which is meant to do fancy I/O redirection then you’ve got a bigger problem.

I present a glorious new solution to the problem. The mdup(3) function does multiple dup operations in one go. You give it a table explaining which file descriptors you want where, and it makes the mappings happen. It will work correctly even if you ask it to map 0 to 1, 1 to 2, 2 to 3 and 3 to 0. If it fails for some reason (probably you hit the per-process fd limit) it leaves enough information lying around that you can work out what state the world is in and clean up properly.

I won’t claim that mdup always does its job in the most efficient way possible — whatever that might mean anyway (probably the smallest number of calls to dup2(2), or runtime). But it is at least correct. And even so, it’s not a completely simple algorithm.

What? You want real code? OK: from my Git repository.

I’m going to try a new approach. Since I’m writing articles at the rate of three and a half every blue moon, I thought I’d recycle material from other places. Here’s one distilled from IRC.

Apparently I’ve acquired a reputation as someone who doesn’t really like the whole object oriented thing. While I never really liked the Kool-Aid, it certainly has its place and it’s often a good way of thinking about a problem. It doesn’t solve everything: nothing does.

Furthermore, it seems that some people have developed the idea that I’m against multiple inheritance, just because I’m down on C++. I usually get thumped by otherwise respectable object-oriented types when I explain that I think multiplie inheritance is actually a pretty neat idea. Oddly enough, they usually think I’m crazy because they’re thinking of C++’s version of multiple inheritance.

C++ is probably the biggest player which actually provides multiple inheritance: later related languages, like Java and C#, have (largely — more on this later) ditched multiple inheritance. And I think the reason is because C++ does such a bad job of it, providing almost none of the features which make it work properly.

About this Archive

This page is an archive of entries from April 2009 listed from newest to oldest.

December 2008 is the previous archive.

October 2009 is the next archive.

Find recent content on the main index or look in the archives to find all content.

Pages

OpenID accepted here Learn more about OpenID
Powered by Movable Type 5.2.13