Posts for 2011 April

Know your history (at least in bash)

Post by Nico Brailovsky @ 2011-04-28 | Permalink | 2 comments | Leave a comment

I always wonder why do you see so many people pressing up a bazillion times when trying to bring a command they recently typed. Just use ctrl+r and type part of the previous command, it'll save you many hours of pressing up.


Cool C++0X features III: Variadic templates, a fix for varargs

Post by Nico Brailovsky @ 2011-04-26 | Permalink | Leave a comment

Last time we saw why a function with varargs may bring lots of problems. Then we saw how to solve it, but never explained why that last solution doesn't have the problems the varargs solution had, nor how does it work. Let's start by copying the solution here:

// Stop condition
void println() {}
// General case
template 
void println(H p, T... t)
{
   std::cout << p;
   println(t...);
}
int main() {
   println("Hola", " mundo ", 42, 'n';);
   return 0;
}

It certainly looks much better than the varargs function, even though some new strange syntax has been introduced. Keep in mind some template-foo is required, not only because of the syntax but because we'll be talking about functional programming too.

With all that intro (the last 2 articles were just an intro!) now we are in a good shape to ask what a variadic template really is. In its easiest form, it's just a list of template arguments, like this:

template  void foo(T... t) {}

That simple template can accept as many parameters as you need, of any type. This is much safer than a vararg because:

Pretty neat, huh? But how does it work? Variadic templates are actually very similar to how Haskell handles lists, you get all the arguments as a list of types in which you can either get the head or the tail. To do something useful, get the head and continue processing the tail recursively.

template 
void do_something(H h, T... t)
{
    // Do something useful with h
    really_do_something(h);
    // Continue processing the tail
    do_something(t...);
}

Of course, you'll eventually need a condition to stop processing: (we'll explain the new syntax later)

void do_something()
{
    // Do nothing :)
}

When the list is completely processed the empty do_something function will be called. Easy, right? But it does have a lot of weird syntax. Let's see what each of those ellipses mean:

With all that in mind, let's put together our typesafe printf:

// Condition to stop processing
void println() {}
// Println receives a list of arguments. We don't know it's type nor
// how many there are, so we just get the head and expand the rest
template 
void println(H p, T... t)
{
    // Do something useful with the head
    std::cout << p;
    // Expand the rest (pass it recursively to println)
    println(t...);
}
int main() {
    // See how it works even better than varargs?
   println("Hola", " mundo ", 42, 'n');
   return 0;
}

Next time, we'll see a more complex (and fun) example of variadic templates.


echo "Hola mundo" > /dev/full

Post by Nico Brailovsky @ 2011-04-21 | Permalink | Leave a comment

I'd write something witty but there's not a lot to talk about /dev/full. Anyway, it is a cool tip, so I'll share it:

Everyone knows /dev/null, and most will know /dev/zero. But /dev/full was unknown to me until some time ago. This device will respond to any write request with ENOSPC, No space left on device. Handy if you want to test if your program catches "disk full" - just let it write there

From Myon's Blog


Cool C++0X features II, Variadic templates: What's wrong with varargs

Post by Nico Brailovsky @ 2011-04-19 | Permalink | 1 comments | Leave a comment

Last time we explained what variadic templates are. We'll see what they can do now. We mentioned that solving the problem of having a type-safe varargs is one of the best ways of applying variadic templates, but what's varargs?

Varargs functions (from C world, not even from C++!) are functions which have a variable number of arguments, just like printf. These are usually very dangerous functions, since they are not typesafe. Let's see how they are implemented with an example:

#include 
#include 
// My god, it's full of bugs
void va_println(int args_left, ...) {
   va_list arg_lst;
   va_start(arg_lst, args_left);
   while(args_left--) {
      const char p = va_arg(arg_lst, const char);
      std::cout << p;
   }
   va_end(arg_lst);
}
int main() {
   va_println(3, "Hola ", "mundo", "n");
   return 0;
}

This implementation of a function with variable arguments is, more or less, the best C can give us, yet it riddled with bugs and hidden problems. Let's go one by one:

#include 
struct X { virtual ~X(){} };
void va_println(int args_left, ...) {
   va_list arg_lst;
   va_start(arg_lst, args_left);
   while(args_left--) {
      X p = va_arg(arg_lst, X);
   }
   va_end(arg_lst);
}
int main() {
   X x, y, z;
   va_println(3, x, y, z);
   return 0;
}

And how do we fix it?

The fix is easy. Too easy. You just need C++0X. We will discuss why this is better next time, but just as a sneak peak:

void println() {}
template  void println(H p, T... t) {
   std::cout << p;
   println(t...);
}
int main() {
   println("Hola", " mundo ", 42, 'n');
   return 0;
}

Remember to compile using -std=c++0x in gcc.

(Thanks Hugo Arregui for correcting the POD example)


Cool C++0X features I: Intro

Post by Nico Brailovsky @ 2011-04-18 | Permalink | Leave a comment

C++0X brings some very cool changes, and I wanted to start a series of posts regarding some of these changes, with a small explanation of each new feature (that I currently understand, at least), an example of its usage and why I think it's a cool thing. Notice these two may be mutually exclusive, some of these may just be cool but I wouldn't recommend using them on a day to day basis. An example of a very cool feature which I wouldn't normally use in a project is the one I want to write about today: variadic templates.

What's not to love about variadic templates? Its name implies (correctly) that it uses templates, and it also has a "variadic" thingy, which you can use to look smart since no one really knows what it means.

Templates themselves can quickly get complicated if used by unexperienced padawans in the art of martial C++, yet their hypnotic beauty draws every programmer to use them just like flies are drawn to fire. When used correctly they can produce very elegant code; if not for the template programmer, at least for the end user. Yet in all their power, templates in C++ have been lacking a fundamental aspect: a variable number of arguments.

There are ways to work around this limitation, like using a list of types paired with a template-paramlist-object. Sounds familiar? (I know it doesn't, don't worry). You could also generate N constructors, one overload for each parameter count. The drawback, exponential compile time (say, TR1). These are all hacks, which are in place only because there wasn't a safe way of passing a list of types associated with a list of arguments. This is over now with variadic templates in C++0X.

So, what kind of problem would variadic templates solve? Let's name a few: * A typesafe varargs function (a function with a variable number of arguments) * Easily create a template object which acts as a tuple * An easier implementation of a reduce (inject) function

This entry is getting quite long so we'll start seeing these examples on the next post.


Hex dump in C++

Post by Nico Brailovsky @ 2011-04-07 | Permalink | Leave a comment

If you need to work with low level stuff (say communications protocols, compression algorithms, stuff like that) you'll be needing an hex dump function sooner or later. Alex, from Alex on Linux, has a great hex dump function for Python and C.

I added an =NULL for caption, I don't use it.

void hex_dump(char *data, int size, char *caption=NULL)
{
    int i; // index in data...
    int j; // index in line...
    char temp[8];
    char buffer[128];
    char *ascii;
    memset(buffer, 0, 128);
    printf("---------> %s <--------- (%d bytes from %p)n", caption, size, data);
    // Printing the ruler...
    printf("        +0          +4          +8          +c            0   4   8   c   n");
    // Hex portion of the line is 8 (the padding) + 3 * 16 = 52 chars long
    // We add another four bytes padding and place the ASCII version...
    ascii = buffer + 58;
    memset(buffer, ' ', 58 + 16);
    buffer[58 + 16] = 'n';
    buffer[58 + 17] = '';
    buffer[0] = '+';
    buffer[1] = '0';
    buffer[2] = '0';
    buffer[3] = '0';
    buffer[4] = '0';
    for (i = 0, j = 0; i < size; i++, j++)
    {
        if (j == 16)
        {
            printf("%s", buffer);
            memset(buffer, ' ', 58 + 16);
            sprintf(temp, "+%04x", i);
            memcpy(buffer, temp, 5);
            j = 0;
        }
        sprintf(temp, "%02x", 0xff & data[i]);
        memcpy(buffer + 8 + (j * 3), temp, 2);
        if ((data[i] > 31) && (data[i] < 127))
            ascii[j] = data[i];
        else
            ascii[j] = '.';
    }
    if (j != 0)
        printf("%s", buffer);
}

Newsflash: C++ object commits sepuku

Post by Nico Brailovsky @ 2011-04-04 | Permalink | 1 comments | Leave a comment

Check this out. Is it valid C++?

class X {
  void dispose() {
    delete this;
  }
};

Strange pattern, isn't it?. What happens if you try to dispose a heap object?

void f() {
   X x;
   x.dispose();
}

Indeed, nasal demons FTW, you're trying to free an invalid pointer. Yet if we change that a little bit...

void f() {
   (new X)->dispose();
}

Zomg now it works. It's weird, but it works. Why would anybody on earth do something like this? Can you guess when would this be useful?

Some times you launch a background job, and you don't really care when it's done. You may use a callback to be notified when the job is done, but if you don't really care then having an object which deletes itself is an option. You'll have to be very careful about it, though, because this is legal C++ too:

class X {
  void dispose() {
    delete this;
    std::cout << "Hello worldn";
  }
};

Though "Hello world" will be printed, it will be running in a dead object. Which is fine, as far as the compiler cares, but if you do try to reference the this pointer, you'll be in a lot of trouble.

Bonus reading For a much more interesting note than mine, go and check When does an object become available for garbage collection? in The Old New Thing.