ExpandCollapseNext Index

+ 1.1 Machine Addresses

Felix provides some types which are used to manipulate machine addresses and memory at a low level.

The type address is basically a C void*. However, you can add or subtract an integer from an address, as if it were actually a C unsigned char*, and of course you can also just increment or decrement an addess.

Addition of an integer to an address is modular, that is, the addition may cause wrap around like an unsigned integer type.

Addresses are totally ordered and support the usual comparisons however addition is not confluent with comparisons:

x > y does not imply x + 1 > y + 1

You can also subtract two addresses, the result is of type ptrdiff. This is a signed integer type with the same number of values as there are addresses. If the addresses are close and the first address is larger than the second the result is positive, negative if they're ordered the other way. If the addresses are a long way apart, in particular more than half the total number of addres value distant, then the difference goes through the maximum value to the zero value and the sign is the opposite of what is expected. In particular the absolute value of the difference is the shortest distance between the addresses around the address circle.

Therefore, the difference operation is also not confluent with comparisons, that is,

x < y does not imply y - x > 0

In particular if x is very small, and y is very big then whilst mathematically y-x > 0, the ptrdiff will instead be a small negative value.

To solve this problem Felix also provides two more types: intptr and uintptr which support the same number of values as an address: intptr is identical to ptrdiff whereas uintptr is unsigned.

Casting a pointer difference to uintptr is confluent with comparisons. If y > x then (y-x).uintptr is precisely the mathematical value of the difference. If the pointers are reversed the value is the mathematical result (which is negative) added to the number of values (one more than the maximum).

Addresses cannot be dereferenced.

An address can be obtained from any pointer or integer. You can also cast an address to any pointer type, the onus is on you, the programmer, to ensure the address actually pointers to store containing a value of that type.

The type

  &byte

supports the same operations as an address except it can be dereferenced.