Why C# is better than C++
06 May 2010This post was imported from blogspot.
I could phrase this as "why I hate C++" or "why C++ sucks", but let's try the more positive spin, "why C# is better". The reasons are so numerous and compelling that there is only one reason to use C++ instead, and that is better performance.- C# compiles much faster
- IntelliSense is much more reliable and faster (press F12 in Visual Studio to see the definition of any symbol)
- Automatic memory management cuts your development time in half all by itself - not just because you write less code, but also because you'll never have to track down "double free" problems and you'll very rarely have memory leaks (and if do you have memory leaks, CLR profiler can help track them down)
- No weird errors caused by #include order or #defines
- No more buffer overflows or other C-related security vulnerabilities
- Debugging is much easier; you can execute arbitrary expressions and call your own functions and properties from within Visual Studio's debugger (and SharpDevelop, I expect)
- Strings are handled the same way in all code (no more converting between various string representations)
- C# has anonymous inner functions with type inference (but the newest version of C++ has so-called "lambdas" too)
- GUIs are easier to make in C# (at least if you use WinForms. I found WPF very hard to learn)
- LINQ (Language INtegrated Query)
- "yield return" statement for writing generators and coroutines (approximate C equivalent)
- You can create and compile code at run-time using Reflection.Emit, Dynamic Methods or (easiest) LambdaExpression.Compile. These use the JIT engine to produce new machine code at run-time.
- The .NET standard libraries ("BCL") have more capabilities than those of C++, and the STL is more cumbersome (object->my_vector.erase(object->my_vector.begin() + index), anyone?)
- Unlike C++ templates, C# generics are guaranteed to work for all type parameters, do not bloat your code size, and can be used by modules linked dynamically (mind you, C++ templates can do some things that are hard/impossible for generics, but advanced use of templates is difficult)
- The MS C# compiler gives much better error messages than the MS C++ compiler
- You can mix different programming languages much more easily in .NET. Bjarne Stroustrup said, "I consider the idea of one language, one programming tool, as the one and only best tool for everyone and for every problem infantile"--yet C++ isn't designed to inter-operate with any language other than C. You can use SWIG if necessary, but it's got a big learning curve and C++ can't take credit for it anyway. On Windows, COM is a possible solution, but it's a huge pain to write COM classes in C++.
- There are various tools for analyzing and modifying .NET assemblies/programs after they are compiled, e.g. PostSharp provides aspect-oriented programming and Microsoft Code Contracts let you specify preconditions, postconditions and invariants in your classes.
- You can easily see how the standard libraries work in their binary form, using Reflector (the source code of the BCL is also available).
- You can write "safe" code that can run directly in a web browser (Silverlight)
- It is possible to write a C# program that targets a mobile device (ARM) and run the same binary on your desktop PC
- You'll no longer have to manage *.h files and write every function declaration twice. Well, you can save yourself work by leaving short"inline" functions in the header file, but you'll pay for it later with slower compile times.
The need to use a different syntax for member functions in the header file than the implementation is a huge pet peeve of mine. Consider the difference between the header file declaration "virtual std::string Name(bool longForm = false);" and the cpp file equivalent "string ClassName::Name(bool longForm) { ... }". In C++ I'm expected to manually remove "virtual", "= false" and the semicolon, but add "ClassName::". Plus you might want to remove "std::" if you're "using namespace std" in the cpp file. Doing all this a few dozen times in a day can drive me mad, and of course the two copies make maintenance harder too. - Dynamic linking and reflection make it easy to support plug-in architectures, and to use 3rd party libraries without compiling them yourself.
- No more dependency-detection glitches where you change a struct or virtual function table but not all dependencies are recompiled, leading to bizarre and unpredictable run-time behavior. In C# I never see such glitches, and if they did happen you would get a run-time exception rather than weird crashes or strange behavior.
- C# IDEs support automatic refactoring and Visual C# underlines syntax and semantic errors as soon as you make them. No such luck in C++!
Unfortunately, I still have to use C++! It is still the performance king and the standard on Windows platforms, and I maintain a performance-critical project for WinCE, on which .NET performs poorly.
Unfortunately, whereas C++ code may be 20 times slower when it runs on mobile (ARM-based) devices compared to a desktop PC, C# on the Compact Framework seems to be closer to 100 times slower than the same C# code running on a desktop PC. Microsoft needs to put a lot more work into their ARM version! Also note that Compact Framework has fewer features (e.g. no support for run-time code generation).
Update: Long after writing this blog post I made a C++ vs C# benchmark. The conclusions were exactly as I expected/feared: C# is often almost as fast as C++ (but about half as fast in certain cases), while the Compact Framework is 3-11 times slower than C++.
Now as much as I hate C++, and prefer C# over Java, the .NET Framework is far from perfect. Some parts of the BCL were badly designed, and by now it is getting to be extremely bloated. Also, I think the .NET framework needs some new features. Chief among my requests would be Go-style slices and interfaces, and return type covariance (of course). This would bring a lot of C's big-fiddling prowess to C# without compromising type safety. You know, that deserves its own blog entry.