Posts for 2011 June

LD magic in Linux

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

The linker is a magical beast which does all sort of crazy stuff with your binaries, without you even knowing it. Every Linux install has a linker living in the shadows, though seeing it in action is a rare supernatural event. There is an ancient tradition to communicate with the spirit of your linker. Not many know about this secret dark path and it's powers to annoy even the most experienced (L)user.

You may begin your journey with the following enchanting:

export LD_DEBUG=help

If everything went fine nothing will seem to happen, yet if the gods of the console have heard you, the next time you try to run any binary at all you'll start to see the real magic. Try it, a simple "ls" will do the trick (don't use commands which are not binaries, like echo or export, these are "hardcoded" in bash, so to speak, and won't work since no runtime linking is necessary: they have already been linked when bash started!).

Read the help you just found. There is a lot of useful information there. Knowing the libs will give you an insight on the dependencies and the loading process of a binary. I have no idea what would be the use of knowing the files for each lib. The symbols and bindings are quite interesting, they remind me of an strace.

"all" is probably the best option to annoy a fellow programmer. Just set the env var and watch him go crazy.


Cool C++0X features X: type inference with decltype

Post by Nico Brailovsky @ 2011-06-10 | Permalink | Leave a comment

After creating a wrapper object on the last entries, we were left with three syntax changes two analyze:

We already saw the first, and we'll be talking about the other two this time. This was the original wrapper function which led us here:

template 
auto wrap(Args... a) -> decltype( do_something(a...) ) {
    std::cout << PRETTY_FUNCTION << "n";
    return do_something(a...);
}

Back on topic: decltype This operator (yes, decltype is an operator) is a cousin of sizeof which will yield the type of an expression. Why do I say it's a cousin of sizeof? Because it's been in the compilers for a long time, only in disguise. This is because you can't get the size of an expression without knowing it's type, so even though it's implementation has existed for a long time only now it's available to the programmer.

One of it's interesting features is that the expression with which you call decltype won't be evaluated, so you can safely use a function call within a decltype, like this:

auto foo(int x) -> decltype( bar(x) ) {
    return bar(x);
}

Doing this with, say, a macro, would get bar(x) evaluated twice, yet with decltype it will be evaluated only once. Any valid C++ expression can go within a decltype operator, so for example this is valid too:

template 
auto multiply(A x, B y) -> decltype( xy )
{
    return xy;
}

What's the type of A and B? What's the type of A*B? We don't care, the compiler will take care of that for us. Let's look again at that example, more closely:

-> (delayed declaration) and decltype Why bother creating a delayed type declaration at all and not just use the decltype in place of the auto? That's because of a scope problem, see this:

// Declare a template function receiving two types as param
template 
// If we are declaring a multiplication operation, what's the return type of AB?
// We can't multiply classes, and we don't know any instances of them
auto multiply(A x, B y)
// Luckily, the method signature now defined both parameters, meaning
// we don't need to expressly know the type of AB, we just evaluate
// xy and use whatever type that yields
    -> decltype( xy )
{
    return x*y;
}

decltype As you see, decltype can be a very powerful tool if the return type of a function is not known for the programmer when writing the code, but you can use it to declare any type, anywhere, if you are too lazy to type. If you, for example, are very bad at math and don't remember that the integers group is closed for multiplication, you could write this:

    int x = 2;
    int y = 3;
    decltype(xy) z = xy;

Yes, you can use it as VB's dim! (kidding, just kidding, please don't hit me). Even though this works and it's perfectly legal, auto is a better option for this. We'll see that on the next entry.


sshfs, quick remote mount

Post by Nico Brailovsky @ 2011-06-09 | Permalink | 4 comments | Leave a comment

When all you have is ssh access to a machine you have enough to mount a remote disk to your work station. How? easy:

sshfs user@host:/path/to/remote/dir /path/to/local/dir

Remember you need permission for both local and remote directories.


Cool C++0X features IX: delayed type declaration

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

In the last two entries we worked on a wrapper object which allows us to decorate a method before or after calling (hello aspects!), or at least that's what it should do when g++ fully implements decltypes and variadic templates. Our wrapper function looks something like this (check out the previous entry for the wrapper object):

#include 
void do_something() { std::cout << PRETTY_FUNCTION << "n"; }
void do_something(const char*) { std::cout << PRETTY_FUNCTION << "n"; }
int do_something(int) { std::cout << PRETTY_FUNCTION << "n"; return 123; }
template 
auto wrap(Args... a) -> decltype( do_something(a...) ) {
    std::cout << PRETTY_FUNCTION << "n";
    return do_something(a...);
}
int main() {
    wrap();
    wrap("nice");
    int x = wrap(42);
    std::cout << x << "n";
    return 0;
}

After the example, we were left with three new syntax changes to analyze: * -> (delayed declaration) * decltype * auto

Let's study the -> operator this time: -> (delayed declaration) This is the easiest one. When a method is declared auto (I've left this one for the end because auto is used for other things too) it means its return type will be defined somewhere else. Note that in this regard the final implementation differs from Stroustroup's FAQ.

The -> operator in a method's definition says "Here's the return type". I'll paste the same simple example we had last time, the following two snippets of code are equivalent:

void foo() {}

Is the same as:

auto foo() -> void {}

Vim: Ni! Ni! Ni! Ni!

Post by Nico Brailovsky @ 2011-06-02 | Permalink | Leave a comment

Even though I have vim a Vim fan for a long time there still is a lot of stuff which amazes me about this little editor, and this thing I last learned about it is in the "ZOMG that's so cool I'm about to pee my pants" category. Unfortunately, if I were to draw a Venn diagram of the people who may find it cool I'd have to intersect the group of people reading my blog (yes, very small) with the group of people who like Vim and Monty Python. So, here's to the null group:

Type :Ni! in Vim and be amazed, it'll reply back: Do you demand a shrubbery?

Just how cool is that?