Nicolás Brailovsky


A modern blog

Search Results

save Jul-20-2010

Template metaprogramming XI: Hidden Agenda

Wow, number eleven already. We’re getting more chapters here than Final Fantasy games. I didn’t even imagine there was so much to write about such an esoteric language features like templates. I do wonder if anyone will actually read it, but that’s a completly different problem.

Enough meta-meta talk: what can we do with all the things we have learned? We can calculate pi and e, we already showed that as an example on one of the first chapters. This chapter I’m going to write about what motivated me to explore the bizarre underworld of template metaprogramming. Some time ago I had to work with a Berkeley DB researching the feasibility of developing a magic cache for (real) DB table. Leaving aside the discussion of whether this is a good idea (the project did have a good reason to be researched) I hit a major roadblock when trying to provide a façde for every table; something like this: See the problem? To do something like that we’d need a virtual template method, and you can’t have that. After seeing that I thought to myself “Hey, I’ll use templates!”. Then I had two problems, but the damage was done, I couldn’t go back. What kind of contorted device could we implement to make such a devious requirement work? I’ll leave you to think it, the answers I came up with next week.

filed Posted under C++, Templates and the tags
save Apr-10-2010

I hearth Berkeley

  1. error: cannot convert ‘Db**’ to ‘DB**’ for argument ‘1’ to ‘int db_create(DB**, DB_ENV*, u_int32_t)

Thank you very much, Oracle Berkeley, for having a type named Db and another one named DB, and for never using namespaces. It makes my work a much more interesting challenge (*).

(*) Yeah, I know, Db is for the C++ wrapper and DB is for the plain C API (**). So what, I hate you all anyway.
(**) I’m working on a project with Berekley DB and it has enough WTF moments for a complete blog… I may post some of them, as a catharsis method. (***)
(***) Or because it has some interesting stuff too… who knows. Recursive note FTW (**). I think I have already done that, haven’t I?

filed Posted under C++, Grumpy and the tags
save Mar-29-2010

Operator sizeof (AKA Reading Berkeley’s FM, take II)

Last time I told you about an evil snipet I found on Oracle Berkeley DB’s manual:

  1.  skey->size = sizeof((struct student_record *)pdata->data)->last_name;
And we concluded it’s trying to… well, dereference a number. And yet it compiles. What the hell is going on there?

The answer here is in the subtleties of the sizeof operator. That’s right, operator, not function. Plus is an operator. Less is an operator. * is a (unary) operator. sizeof is a unary operator too. The relevance of this is that operators can behave in more bizzare ways than functions do. In this case there’s a difference between this two lines:

  1.  MyClass x;
  2.   int a = sizeof(MyClass);
  3.   int b = sizeof(x);

A very subtle difference. Can you spot it? a and b will have the exact same value, rest assured. The difference is in the operator itself: sizeof MUST have parenthesis when applied to a type name, yet parenthesis are optional when applied to an instance of a datatype, so this code is legal:

  1.  MyClass x;
  2.   int a = sizeof(MyClass);
  3.   int b = sizeof x;

Oh, wait, the fun doesn’t stop there: sizeof also has bizarre precedence order, meaning it won’t get applied as you expect it. So, this is valid too:

  1.  struct MyClass { int y; } x;
  2.   int b = sizeof x->y;

Can you see where we are going? Knowing that sizeof will be applied last lets you write something like this too:

  1.  void *ptr = …
  2.   int b = sizeof((X*)ptr)->y;

Which means nothing else than “store in b the size of member y in struct X. It should be easy to see why BDB’s example does compile, and why did I spend half an hour trying to understand the reason it compiled fine.

By using some more casts and a clever arangement of parenthesis you can come up with a great job security device.

filed Posted under C++, Grumpy, Programming, WTF and the tags
save Mar-26-2010

Reading Berkeley’s FM

I got this from Oracle Berkely DB’s FM:

  1.  skey->size = sizeof((struct student_record *)pdata->data)->last_name;

Take a good look at that pice of code:

  1.  a_number = sizeof((T*)pdata->data)->last_name;

Again:

  1.  a_number = sizeof(Whatever)->field;

Wait a minute. typeof(sizeof(x)) == const unsigned int. Right? So, again:

  1.  a_number = 42->field;

There’s no way that first line can compile. Go and check it (in the example, not the last line please). I’ll wait. Done? Yeap, I was surprised to, it does indeed compile. Mi first reaction towards this discovery went something like this:

What is going on there? It took me a while to figure out how evil Berkely ’s manual can be. The answer next time.

filed Posted under C++, Grumpy, Programming, WTF and the tags
save Mar-25-2010

I hate Berkeley

Polymorphism taken to 11:

SQL Term Oracle Berkeley DB Equivalent
Database Environment
Table Database
Tuple/row Key/data pair
Secondary index Secondary database

WTF ORACLE, WTF.

filed Posted under Grumpy, Programming and the tags
save Feb-19-2010

Valgrind – OCI: Suppressions file, Take II

valgrind-link3

Remember my OCI suppressions file? Well, since then I have updated it. Now it includes some more suppressions, for libnetsnmp, Oracle, Berkeley DB, and may be something else I can’t remember.

If you add anything else let me know in the comments.

BTW last time attaching this file failed so now I’m posting it in the first comment after this entry.

filed Posted under Programming and the tags