3 ms·
That's not really true, at least not with C. C doesn't permit arbitrary pointer arithmetic. e.g. If you take a pointer to the first element of an array and dec
by parenthephobia 11y ago
That's not really true, at least not with C.
C doesn't permit arbitrary pointer arithmetic. e.g. If you take a pointer to the first element of an array and decrement it, the behaviour is undefined. It's permissible for the GC to crash your program in that situation. You don't need to dereference it: just having that pointer, even ephemerally, is undefined behaviour.
If you deallocate an object, then all pointers to that object are, technically, rendered as-though uninitialized: it is undefined what happens if you even attempt to determine the address of a previously-deleted object. This permits implementations to set dangling pointers to NULL.
Finally, a pointer to e.g. an int can't be used to access e.g. a float at that location. It is valid to convert an int pointer to a float pointer, but the consequences of dereferencing it are undefined. An exception exists for characters: any pointer can be converted to a char pointer and used to read the bytes of the object.
The upshot is that every pointer in C always points at a valid object of a known type - or just-allocated memory which hasn't had a value put in it yet - or the GC is allowed to crash the program. Of course, most (all?) compilers don't actually generate code where it's always possible to find out what type of object a pointer is pointing at, or even whether the pointer has actually gone out of range.
The real issue in C - other than a lot of code depends on the above rules not being enforced - is that it's valid to convert a pointer to an integer, store it for long enough for an eager GC to remove the object, and then convert that integer back to a pointer. Now you have an invalid pointer, but the standard doesn't allow the pointer to become invalid. That means the only valid GC must assume any integer might be a pointer in disguise (unless it can prove it could never be converted into a pointer), and it can't move objects around either, because it can't just go modifying integers which might be pointers to those objects.
- haimez 11y agoNotably, this also prevents being able to implement functionality required for performant GC, like generational collection (as moving references is virtually impossible without controlling the runtime).