It's safe to dereference in the same thread.

A `thread_local`'s actual virtual address is not merely what the pointer contains - it's an offset from some other virtual address stored in the FS or GS register (on x86-64), which is swapped when you change thread. Casting the pointer to `intptr_t` does not retain the segment base address - only the offset. The pointer is not the absolute address.

If you dereference in another thread, it's the same offset, but from a different base address.

There may be other things besides segment registers on other architectures that also make it unsafe. The C standard makes no guarantee that you can safely dereference a pointer cast from `intptr_t`.

I’m sorry but this is just incorrect. When you take the address of a thread local variable you have to lookup its real address using something like __tls_get_addr or by reading its offset via fs/gs but once it’s in a pointer it’s just a regular absolute address and is fine to dereference on any thread. There is no separate type for a pointer to a thread local variable.

That's an implementation choice. The standard makes no such guarantees.

> An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, may not be correctly aligned, may not point to an entity of the referenced type, and can produce an indeterminate representation when stored into an object

The compiler may specify otherwise. GCC specifies that the pointer cast to integer back to pointer must point to the original object, else the behavior is undefined.