https://en.wikipedia.org/wiki/Garbage_collection_(computer_s...
Reference counting is definitely a method of garbage collection.
So if your program allocated less than available, doing nothing would be a valid GC strategy as your program never hit an upper bound in what it can allocate.
I found that an interesting way to think about the problem because it's more concerned with what GC enables instead of what it strictly does. The former is always the same, no matter the GC implementation, but the latter can vary considerably (doing nothing, reference counting, mark-and-sweep, full concurrent and compacting GC, ...).
Interestingly, this is also the description of Virtual Memory. https://en.wikipedia.org/wiki/Virtual_memory
GC is an abstraction that can work well but can also interfere with how a developer thinks.
Yep, this is a big issue.
Another good example is copying arrays of primitive types with for loops instead of using intrisics like System.arrayCopy().
Or using lists instead of arrays.
Sure there are many situations where there is no another way other than step out of the JVM into C++, but many could be avoided with better code as well.
Chapter 5.
One of the best CS references in GC algorithms.
I can post links to 70's papers if you wish, specially ones related to Lisp research.
See page 6, remark 7 in 'Uniprocessor garbage collection techniques', Paul Wilson:
http://scholarworks.rit.edu/cgi/viewcontent.cgi?article=1322...
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n267...
Also, there are the C++/CLI and C++/CX that support GC at language level.
Now std::*_ptr<> types don't count to make the language GC, because their use is not enforced by the compiler.
We're talking about garbage-collected languages (and "language" traditionally includes the standard library), not garbage-collected-only languages.
I mean, by your definition, C# also doesn't count, because it has unmanaged pointers in it.
In C#, GC is part of the language semantics and its interaction with unmanaged pointers is well defined in the language semantics standard, including how the memory is pinned when unmanaged pointers need to access GC allocated memory.
If reference counting is a kind of GC, and the standard library offers reference counting, then the language offers a kind of GC - same as if the language itself had a built-in refcounted pointer. There's simply no practical difference here.
It only makes sense to talk like that, if the language semantics define a relationship between the language and library requiring the library to always exist as a form of runtime and how the use of that runtime relates to language constructs.
If I can just throw away the library and replace it by something else where those types aren't available and still make use of 100% of the language features, this relationship doesn't exist.
There's a single document defining what is ISO C++. It defines both the language and the standard library. Therefore, to "write in C++", by default, means to write code that uses and relies upon both the language semantics and the standard library functionality. Which means that std::shared_ptr etc is readily available, and is the standard way to use refcounting-based GC in C++.
Hence, ISO C++ is a language with optional refcounting-based GC.
Then you also shouldn't say that Swift is garbage collected.
C++ language definition doesn't give any special treatment tostd::*_ptr<> types regarding compiler semantics. They could be be something else.
Library types like std::shared_ptr don't really count to say that a language has a GC, because their use, specially their correct use, is not enforced by the compiler.
Although, there are conservative GCs for C that replace malloc () and make fre () a nop, they cannot release all memory properly due to C semantics.