int pointer 依照記憶體對齊的特性,一定會排在記憶體位置可被 4 整除的位置上(binary 最後兩位為 0),所以可以在最後兩位儲存不大於 4 的資料。

#include <stdio.h>
#include <assert.h>
 
int main() {
    assert(sizeof(int) == 4);    
    int x = 701;
    int x2 = 702;
    int x3 = 123;
    int *p = &x;
    int *p3 = &x3;
    int *p2 = &x2;
 
    printf("pointer 1: %p \n", p);
    printf("pointer 2: %p \n", p2);
    printf("pointer 3: %p \n", p3);
    // pointer 1: 0x16cfcaf5c 
    // pointer 2: 0x16cfcaf58 
    // pointer 3: 0x16cfcaf54 
    // c, 8, 4(hexidecimal) in binary all ends with at least two 0.
}
 
#include <assert.h>
#include <stdio.h>
 
void put_data(int* ptr, unsigned int data) {
  assert(data < 4);
  *ptr |= data;
}
 
unsigned int get_data(int* ptr) {
  return (*ptr & 3);
}
 
void cleanse_pointer(int* ptr) {
  *ptr &= ~3;
}
 
int main() {
  int x = 701;
  int* x_addr = &x;
 
  printf("x's address: %p\n", x_addr);
 
  put_data(&x_addr, 3);
  printf("x's address after putting data in: %p\n", x_addr);
 
  printf("data stored in x's address: %d\n", get_data(&x_addr));
 
  cleanse_pointer(&x_addr);
 
  printf("Cleansed ptr: %p\n", x_addr);
  printf("Dereferencing cleansed ptr: %d\n", *x_addr);
 
  return 0;
}
 
/*
x's address: 0x16ba9b0e8
x's address after putting data in: 0x16ba9b0eb
data stored in x's address: 3
Cleansed ptr: 0x16ba9b0e8
Dereferencing cleansed ptr: 701
*/
struct rb_node {
	unsigned long  __rb_parent_color;
	struct rb_node *rb_right;
	struct rb_node *rb_left;
} __attribute__((aligned(sizeof(long))));
/* The alignment might seem pointless, but allegedly CRIS needs it */
 
struct rb_root {
	struct rb_node *rb_node;
};

__rb_parent_color stores the parent’s address.

#define rb_parent(r)   ((struct rb_node *)((r)->__rb_parent_color & ~3))

技巧同上述的 cleanse_pointer,先將顏色去除,就可得到真正的 address。

Reference