Why C++ for Unreal 4?

[=nlaq;18180]
Did you read the thread? There are quite a few garbage posts such as:

The comment you were referring to was directed at posts such as these.

Note that in my reply, I did state that native code is a very appropriate choice for many of the performance critical subsystems in the engine; but may be significantly less so for game logic, AI, networking code and so on (i.e. a majority of the game-specific logic you may wish to implement).

[/]

My apologies about that one, I did in my haste filter out those sorts of posts and didn’t consider them as anything but noise (certainly they aren’t well reasoned debates).

And of course that’s all we are doing here is debating the pros and cons here of which there are many facets.

[=nlaq;18180]
That’s because C++ being inherently faster than C# is a myth. Writing the same logic in either language will produce fairly similar results in regards to performance; C# is compiled into IL, IL is compiled (at runtime) into machine code…
[/]

That’s not a statement that’s born out in reality and testing. There are cases where C# can be as fast, but saying that in general a JIT’ed language is just as fast as C++ glosses over an enormously complex and varied set of circumstances. The Mono optimizer typically employed by users of Unity is much slower than the IL that is compiled by a microsoft JIT optimizer. And even in the the later example, certain parts of the IL specification (like as you mention indexing) eliminate some types of optimizations that can be done.

It’s my opinion your assertion that C# is as fast as C++ is false in general, and true in certain cases. It’s also my opinion that C# is plenty fast and reasonable to do a large variety of things in.

http://creamysoft.blogspot.com/2013/05/c-vs-c-performance.html

The next article is much more exhausting and examines head to head comparisons of C# and C++ in a large variety of isolated cases, as well as larger programs. In almost every case C++ is faster by a factor of at least 2. One of the later programs, a Soduku solver runs 200% faster in C++.

http://www.codeproject.com/Articles/212856/Head-to-head-benchmark-Csharp-vs-NET

[=nlaq;18180]
There are certain things that the runtime does that makes it slightly slower (array references are bounds-checked for example - though scoff at this all you want, but this feature has removed a metric crapload more critical (and potentially security related) bugs than C#'s lack of constness has added).
[/]

I don’t scoff at that feature by any means but that’s a security feature not a stability feature. An IndexOutOfBounds exception is typically a fatal error, or will at least lead to undefined behavior. I don’t see that as necessarily beneficial to have in game-code, where security and in particular memory overrun exploitation bugs are not an issue you are typically designing around.

If your point was that you can find those errors faster, as they happen, then you are just not aware that C++ provides similar and potentially superior ways of doing the same thing (for example boost:array). The benefit with C++ is that when you are ready to “go fast now” you can disable the indexing checks if you want to.

[=nlaq;18180]
Many other systems, the kinds that a gameplay programmer, tool developer, or AI developer would write are not performance critical. Giving them a leg up in productivity and correctness is worth a slight performance hit - hell, while this figure is absolutely incorrect, I’d even say a 2x performance hit is more than worth it. Remember: these systems do not need to be executed many times in a frame.
[/]

It’s difficult to agree or disagree with this without a better use case. The only thing I can say for sure about whether in general you’ll be more productive writing those systems in C# than in C++ is: it’s complicated, and not necessarily. Dealing with the GC in some of those cases might be a drain on productivity. C# does make certain types of things harder to do, but it also makes some things easier.

[=nlaq;18180]

Safety Features:

  • Array bounds checking

[/]

Identical feature: C++ boost:array (superior because you can optionally disable the checks when you want to “go fast”)

[=nlaq;18180]

  • Better type safety

[/]

Both languages are strict-statically typed. This seems like you are equating the fact that C# has a subset of the type-casting features of C++ as equivalent to “more safe because it lacks that ability”.

[=nlaq;18180]

  • An exception system that developers aren’t embarrassed to use

[/]

Not sure about that one, in my experience they are essentially equal. I don’t litter my code with the nothrow() stuff though. I’ve never really seen a big difference there. Are you talking about C# exceptions vs SEH?

[=nlaq;18180]

  • No raw/dangling pointers

[/]

As a type safety feature I agree.

[=nlaq;18180]

  • Requirement that variables be definitely assigned before access

[/]

C++ catches these cases as warnings. Warnings=error setting is a good practice to have.

OO Features:

[=nlaq;18180]

  • Interfaces

[/]

C# interfaces exist simply to fill in the gap because you don’t have multiple inheritance.

[=nlaq;18180]

  • Better enums

[/]

Agreed.

[=nlaq;18180]

  • Lack of multiple inheritance (I’ve yet to see a proper use-case of multiple inheritance in C++, except in the case where classes with only pure virtual methods are used to emulate interfaces). This especially holds true as the programming industry, at large, now discourages heavy use of inheritance in favor of composition-based OO strategies.

[/]

Not a benefit of the language. Here’s a good use case in C# that illustrates issues with GC and lack of multiple inheritance:

A generic linked list container that puts the linkage pointers inside the class, instead of allocating linkage nodes like the C# library System.LinkedList does:



class Base { // some basic functionality };

// OK I want to make a new class called Derrived that goes into a generic linked list class without having extra heap allocations for the linkage pointers.

class LinkedListNode<T> : where T class { T prev; T next; }

// Can't do this! C# doesn't have multiple inheritence.

class Derrived : Base, LinkedListNode<Derrived> { // do some special things }

// Forced to do this:

interface ILinkedListNode { Next { get; set; } Prev { get; set; } }

class Derrived : Base, ILinkedListNode {
     // Forced to implement ILinkedListNode in every class that goes into my LinkedList.
}



[=nlaq;18180]

  • Arguably better generic type system. C++ templates are glorified macros, while generics in C# are baked straight into the runtime. 90% of cases where C# generics can’t emulate something that you can do with C++ templates are unnecessary in C# - such as traits. Furthermore, generics in C# do not affect the size of the assembly, nor the time it takes to compile.

[/]

C++'s template meta programming is a full turning complete language. To suggest they are glorified macros leads me to suspect you don’t have very much experience with either of them. C# generics are much more restrictive, and don’t perform as well as C++ template code does.

C++ templates do increase compile time and code size, again a trade-off in power and performance vs a less capable but faster to compile feature.

Runtime Features:

[=nlaq;18180]

  • Proper reflection - which includes instantiating generic types at runtime. Yes, reflection can be emulated in C++ though heavy use of templates, but this adversely affects compile times as well as runtime performance.
  • Type safe dynamic code generation via expression trees

[/]

C# wins here, but I’m not sure where this part ties into your game programmer example in particular. I can see reflection being sort of useful as an archetype system or dynamically creating behaviors from XML.

[=nlaq;18180]

Other Features:

  • Unicode (UTF-16) is baked straight into the framework and requires no additional thought. The existence of a string primitive (and lack of support of C-style strings) removes complexity and increases compatibility with third party code.
  • The existence of a delegate type. This, yet again, can be emulated in C++ though clever use of templates and other features - yet, delegates are a first class citizen of the .net world.

[/]

Agreed, but C++11 now has lamba functions and closures now, so the gap has narrowed on that one.

[=nlaq;18180]

Productivity Features:

  • Much, much (much much much much) faster compile times
  • Visual 's C# support, combined with ReSharper, destroy any toolset of any language I have come into contact with. Ever.
  • The way in which the compiler handles errors (C++ errors, especially linker errors, can be quite cryptic)

[/]

Yes. Although some of this is because of C# restricted feature set.

[=nlaq;18180]

C++ is hardly more “expressive” than C#. C++ is a hodgepodge of features that, with dedication and discipline, can be cobbled together into sensible code. Most of the time, however, these “expressive” features of C++ are simply used to emulate features that are inherently available in C# and other .net languages. Slate is some sort of odd subset of C++ that cleverly uses some of C++'s unique features (such as C++'s obscene list of overloadable operators) to create a programming experience that is some kind of imitation of a C# like language combined with a declarative DSL.

Furthermore, it may have been advantageous for Epic to have created an actual, outside-of-C++, DSL for slate layout files. Creating DSLs is incredibly easy to do in C#, especially with tools such as Antlr - and if you combine them with the dynamic code generation features of C#, they can have the same performance characteristics of straight-up managed code.

[/]

The rebuttal here is just a redirection and a handwave that avoids facing the real issue presented with Slate and UObject. I have no doubt a system as feature rich as Slate could have been done in C#. However, Slate and the UObject system brilliantly demonstrates the expressive power of C++ and C# totally lacks the features necessary to do this.