0

I was just going over some kernel code, I noticed that rb->__rb_parent_color = (unsigned long)p | color; is kinda wired. The first field of a struct is accessed by casting the pointer and not by using the field name.

Here is the definition of that struct, as you can see the color is the first attribute, so simply casting (unsigned long)p will give us the same as rb->__rb_parent_color. But why did the developers choose to do it this way and not using the ->?

The only reason I can think of is compiler optimizations that are not done when using rb->__rb_parent_color, but find this hard to believe cause it seems like the compiler will, in both cases, calculate the same offset without problems.

1 Answer 1

1

struct rb_node *p is not dereferenced. Read it again: this code casts the address to an unsigned long.

This is relying on the fact that object addresses are aligned such that the bottom bit (at least) of the address is guaranteed to be un-used, so it packs the colour into that bit. So __rb_parent_color here does not mean the parent's color: it means the parent pointer and its color are stored in this field.

Read the __rb_parent and __rb_color macros above to see how the field is used. (__rb_parent actually implies the bottom 2 bits are un-used, giving 4-byte alignment, but nothing seems to use the second bit either way.)

1
  • Now I also get the name __rb_parent_color. It means first is (a pointer to) the parent, then comes the color of the node itself. Thanks. Nov 2, 2014 at 13:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.