syntax highlight

Thursday 28 April 2011

Know your history (at least in bash)

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.

Tuesday 26 April 2011

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

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 <typename H, typename... T>
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 <typename... T> 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:

  • Doesn't require the user to specify the number of args passed to foo, so it just can't get out of sync
  • It's typesafe; since C++ templates are type-safe, variadic templates are type safe too. You won't be able to request an int where a char is required, you'll just get a compiler error.
  • Compile time check: you get type safety just because this is all compiled code. If it doesn't compile, you get an error (albeit a little cryptic).
  • POD types support
  • Better performance; small gain, but a gain indeed. Since this is all done in compile time there's no need to handle the stack dynamically, nor of having a loop getting the args. It's all known when you compile, thus the compiler can just optimize the hell out of everything

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 <typename H, typename... T>
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:

  • When declaring typename... T you are saying "here goes a list of types". That is, when you use ellipses after the typename (or class) declaration but before the name of the type, then you are expecting a list of types there.
  • When declaring T... t you are saying t is a list of objects with different type. That is, you declared T... as a type which holds a list of types, therefore t, of type T, is an instance of a list of objects, each of different type
  • When you write t..., you are saying "expand the list of arguments". You declared t as a list of objects, but you have no way of accessing each of those objects, just to the list as a whole. When you write the name of the object followed by ellipses, you are saying expand these types and their instance for the called function

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 <typename H, typename... T>
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.

Thursday 21 April 2011

echo "Hola mundo" > /dev/full

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

Tuesday 19 April 2011

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

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 <stdarg.h>
#include <iostream>

// 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:

  • Arg num will get out of sync: You need to specify the list of args as well as how many you have. That WILL get out of sync. Trust me, it's just a mater of time. And when it does, you'll have a coredump.
  • Type-unsafe: You just tell varargs "Hey, get me an int". And it will give you an int, no warranties included. If it was supposed to be a short instead, though luck, you end up with a coredump.
  • No, really, coredump: Where are so many coredumps coming from, you may ask. Easy, varargs it's just a way of handling the stack. Calling va_arg just moves the stack pointer by the sizeof the datatype you requested. That means no compile-time checks are included.
  • No pod types: Remember POD types? Try running this code:
#include <stdarg.h>

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 <typename H, typename... T> 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)

Monday 18 April 2011

Cool C++0X features I: Intro

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.

Thursday 7 April 2011

Hex dump in C++

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);
}

Monday 4 April 2011

Newsflash: C++ object commits sepuku

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.