Our lecturer in C made the following statement:
Whenever a scope of some variable ends, the compiler checks whether this variable was an object itself or a reference to it, thus deciding whether to destroy it and make all references to it invalid (in the 1st case) or leave it as is (in the 2nd case). Therefore, C couldn't have chosen a strategy similar to Python or Java, i. e. perceiving
a = b
as a new referencea
tob
, as in such a case every time a variable leaves its scope the compiler would have to check whether there are any other references to the same object. Keeping trace of such information is basically garbage collection, which is not C -style.
I can't understand one thing: whenever we destroy an object in C , we still risk the appearance of dangling references all over the programme, don't we? And it's fully programmers business to keep trace of them.
Since we are obliged to keep track of dangling references anyway, why does the creation of a reference when assigning IMPLY garbage collection (thus, making it implementable in C )? Or did I get the claim above wrong?
CodePudding user response:
"Since we are obliged to keep track of dangling references anyway"...
Well, it turns out that we generally don't bother with that. As a simple example, consider the copy constructor Foo::Foo(Foo const& source)
. That reference source
exists within the copy constructor, but the source object exists outside the constructor. We can reasonably assume that the caller doesn't destroy the object while it's being copied - that would require a second thread executing on another CPU core, or similar unusual thing. Instead, we rely on a common unspoken agreement: if you copy something, you keep the source object alive until the copy is made.
It turns out that in many cases, C references are short-lived and you don't need to do anything special. This is even more so because C references cannot be rebound - you can't make a reference point to another object later on. For the latter, C has pointers.
In addition to these core concepts, C also has smart pointers. These effectively handle garbage collection for just a single object.
CodePudding user response:
C has copy semantics by default, and reference semantics when explicitly requested. When reference semantics is requested, the programmer is expected to keep track, and avoid use, of dangling references. Reference semantics is usually requested only for a small part of all variables, and reference are usually short-lived, so they rarely dangle.
A language that has reference semantics by default (such as Python or Java) practically requires GC, because in the absence of GC, manual tracking lifetimes of every single variable and object is an unreasonable burden on the programmer. It is theoretically possible to have reference semantics by default and no GC, but when one starts dealing with more than tiniest toy programs, it becomes rather impractical.
Reference semantics by default also destroys RAII, and destroying RAII means destroying C as we know it.