Consider `double* b`. Its pointer type is derived from `double`, its base type. Change the base type and the result is a distinct pointer type: `double*` and `size_t*` are not the same type. This distinction matters when a pointer addresses an object; C reasons about the object's type, not its physical address. section 12.0
C's basic types supply starting points for derived types. They include unsigned integers, signed integers, real floating-point numbers, and complex floating-point numbers. Types within a class differ in precision and valid range. Basic types can be specified with language keywords, while headers also provide types organized by purpose, such as `size_t`. section 5.2
TAKEAWAY: Keep the type distinction when reasoning about arithmetic and memory.
- Narrow integer types are promoted before arithmetic; `char` and `bool` are among them. section 5.2
- Pointers with distinct base types are distinct pointer types. Except for character types, only pointers of the same base type may alias—access the same object. section 12.0 section 12.3
size_t blob(size_t const* a, double* b) {
size_t myA = *a;
*b = 2*myA;
return *a; // Must be myA
}
In `blob`, the parameters have `size_t` and `double` as their underlying base types. The assignment through `b` therefore cannot change the object read through `a` in a valid call; the returned value remains `myA`. section 12.3
Do not try to defeat that constraint by passing pointers that make differently typed parameters address the same object. Such a call can have undefined behavior. section 12.3

