Sunday, August 8, 2010

What's the return value of memset?

I figured I'd start off with something I noticed last week for the first time: memset has a return value!

Every C programmer should be familiar with memset. You've probably used it like this:

void *memory = malloc(100);
if (NULL != memory) {
  memset(memory, 0, 100);
  doSomething(memory);
}

(You did test that malloc succeeded, right?)

I looked up memset last week, and was surprised to see that the man page said it returns void*. I'd always assumed that it was a void function. It turns out that memset returns the first argument.

So you could actually write the above code like this:

void *memory = malloc(100);
if (NULL != memory) {
  doSomething(memset(memory, 0, 100));
}

Why would you do this? Either you're running low on your budget for lines of code, or you like to confuse your collaborators.

So why does memset have a return value when it doesn't need one? I don't know, but my guess is that it's a historic artifact. In some cases it could let you avoid creating a temporary variable to store the pointer. Temporary variables take up space in the stack frame, but return values are usually passed around in registers. In the era before optimizing compilers, that mattered. But a modern compiler will remove temporary variables (or add them) all by itself -- it doesn't need a micro-optimizing programmer to tell it how to do that.

2 comments:

  1. Maybe the return value is the address to destination, *incremented* with the amount of bytes set, did you check for that? That would be useful.

    ReplyDelete
    Replies
    1. No. It's specified to be the destination. An implementation which returned anything else would be non-compliant.

      Delete