For instance if you have a GC that compacts then by definition you cannot guarantee object relative layout. This object layout is critical in making sure that your traversal order is cache and pre-fetch friendly.
AFAIK struts+arrays in C# are the only construct I've seen that lets you get close to explicitly control ordering of objects. In almost every other GC'd language you end up needing to use a giant byte array(hello emscripten!) in order to make those guarantees. If you work in that manner you're throwing away 90% of what makes the language useful and paying the cost of not working with the objects in their native form.
Check Mesa/Cedar, Modula-3, Oberon, Oberon-2, Active Oberon, Component Pascal, D.
All system programming languages with GC.
I'm sure they fit the definition but I don't know that I'd want to use any in production aside from D. D is so similar to C++ I'd just rather use C++ instead since it's a bit more proven of a stack.
The problem is to have an OS vendor that would care to bring those features back.
So far I see it happening with Swift and C#, where Microsoft is slowly adding features from System C# used in project Midori.
Will they kill C++? Surely not, but they might reduce the use cases one would use it for.
For example, nowadays I don't write full stack applications in C++ any longer, I just use it for infrastructure code.
You do that in GC and non-GC environments exactly the same way: by embedding your objects in arrays.
> AFAIK struts+arrays in C# are the only construct I've seen that lets you get close to explicitly control ordering of objects.
And Java's upcoming value types.
> If you work in that manner you're throwing away 90% of what makes the language useful and paying the cost of not working with the objects in their native form.
I disagree. Even without value types, working with byte buffers in Java may still be significantly less work than C++, depending on how much of your application requires this kind of work. And the GC saves you a lot of work when you deal with concurrent data structures.
The main disadvantage (good) GCs have is their significant RAM overhead when good performance is required.
Value types are nice in Java, when will we see them in production? We don't even have Java8 on Android yet so I probably won't be able to use them till ~4-5 years from now.
Byte arrays may be less work but they still have problems, you'll pay the int->float cast costs for one, which can be non-trivial on some platforms. Also if you want to use Strings you end up allocating a new string on each access since Java doesn't have a nice way to wrap an immutable string(take a look at FlatBuffers if you want to see this in more detail).
I think it's important to understand they we're talking about a specific set of areas that C++ excels in. There are certainly places where I think Java and other managed languages make sense but if I need to make performance guarantees I'd rather not shoe-horn in a GC'd language where proven stacks have been successful.
Then you embed the array of chars in the object, just like in C++. I don't see what having a GC has to do with it. As to embedding arrays in objects in Java, I think it's planned as part of the value-type project, but no prototype yet. I know John Rose (JVM architect) said that the two features they intend to address are arrays of structs and structs of arrays (but not buffers of structs of arrays).
> you'll pay the int->float cast costs for one
HotSpot should optimize it away (not sure about byte buffer usage, though). It sees an integer read and a cast to float, and reads directly into a floating-point register.
> Java doesn't have a nice way to wrap an immutable string
You mean mutable string? Well, there's the CharSequence interface that String and the mutable StringBuilder implement, but it's true that not many standard APIs accept a CharSequence.
> I think it's important to understand they we're talking about a specific set of areas that C++ excels in.
I agree. C/C++ is unparalleled for single-threaded traversals over encoded binary data (e.g. video encoding/decoding and other signal processing) and for performance-sensitive applications running in memory constrained environments . Managed runtimes even try to compete in those domains.
In other cases, the extra performance you can squeeze out is too insignificant (and growing less significant with time) to justify the extra effort. And in some cases of growing importance (interesting multi-threading), C++ has to work really hard to even match GC-runtime environments. The real cost that is always paid is the significant RAM overhead.
And BTW: Android isn't Java. It's compatibility with Java has always been very partial, and, of course, its development is not directed by the JCP.
or Go, especially with the value types. Now there is no automatic SoA/ AoS conversions but otherwise, you have full control over memory layout.
In Go:
A struct is laid out as you declared it, with possible compiler added padding. A struct value field (not a pointer) in another struct is laid out contiguously in memory as you declared it. An array (or a slice) of values (no pointers) are laid out contiguously in memory.
You can happily take pointers into any of these larger structures. If you had a data structure where you really wanted to control the layout, you can create a slab allocator as a big array of values, and take pointers into that array to allocate pieces of your data structure. I did this exact thing to write a red-black tree in Go.
It is true that Go's GC isn't compacting. But it will be in the future (or it is planned to be).
But, if I hadn't programmed in Go I would have agreed with your comment above.