Для 2 ^ N-байтового выровненного указателя его адрес всегда делится на 2 ^ N - это означает, что младшие N битов всегда равны нулю. В них вы можете хранить дополнительную информацию:
encode ptr payload = ptr | payload
decode_ptr data = data & ~mask
decode_payload data = data & mask
, где маска (1 << N) - 1
- то есть число с установленными младшими битами N.
Этот прием часто используется для экономии места в низкоуровневом коде (полезные данные могут быть флагами GC, тегом типа и т. Д.)
Фактически вы сохраняете не указатель, а число, из которого можно извлечь указатель. Конечно, следует позаботиться о том, чтобы не разыменовывать число в качестве указателя без декодирования.