when I first saw C#, I thought this must be some joke. I was starting with programming in C. But in C# you could just drag and drop objects, and just write event code to them. It was so simple.
Now, I still like C the most, because I am very attracted to the basic low level operations, and C is just next level of assembler, with few basic routines, so I like it very much. Even more because I write little apps for micro-controllers.
But yesterday I wrote very simple control program for my micro-controller based LED cube in asm, and I needed some way to simply create animation sequences to the Cube. So, I remembered C#. I have practically NO C# skills, but still I created simple program to make animation sequences in about hour with GUI, just with help of google and help of the embedded function descriptions in C#.
So, to get to the point, is there some other reason then top speed, to use any other language than C#? I mean, it is so effective. I know that Java is a bit of similar, but I expect C# to be more Windows effective since its directly from Microsoft.
The second question is, what is the advantage of compiling into CIL, and than run by CLR, than directly compile it into machine code? I know that portability is one, but since C# is mainly for Windows, wouldn´t it be more powerful to just compile it directly? Thanks.
1 - diff languages have their pros and cons. There are families of languages (functional, dynamic, static, etc.) which are better for specific problem domains. You'd need to learn one in each family to know when to choose which one. e.g. to write a simple script, I'd pick Ruby over C#
2 - Compiling it to CIL: Portability may not be a big deal.. but to be precise Mono has an implementation of the CLR on Linux. So there. Also CIL helps you to mix-and-match across languages that run on the CLR. e.g. IronRuby can access standard framework libraries written in C#. It also enables the CLR to leverage the actual hardware (e.g. turn on optimizations, use specific instructions) on which the program is run. The CLR on 2 machines would produce the best native code from the same IL for the respective machine.
Language and platform choice are a function of project goal. It sounds like you enjoy system level programming, which is one of the strong points of using C/C++. So, keep writing systems level code if that's what you enjoy.
Writing in C# is strong in rapid business application development where the goals are inherently different. Writing good working code faster is worth money in both man-hours and time to market. Microsoft does us a huge favor with providing an expressive language and a solid framework of functionality that prevents us from having to write low level code or tooling for 95% of business needs.
One important advantage of IL is language independance. You can define modules in project which should be done in C++, some in C# and some in VB.net. All these projects when compiled give respective assemblies(.dll/.exe). This you can use the assembly for C++ project in the c# one and vice versa. This is possible because.. no matter which language (.net supported) you choose.. all compile to the same IL code.
I'm not sure that C# is more effective only because is a Microsoft product. If you use the Visual Studio, or other RAD, some of the code is auto-generated and sometimes is less efficient. Some years ago I was a dogmatic, thinking only C can response all our prayers :-P , but now I think virtual machines can help a lot in the way to optimize code before to execute it (like a RDBMS), storing in caché pieces of code to execute later, etc. Including the possibility to create "clusters" of virtual machines as Terracotta does. At least the benefits of having an extra abstraction layer are bigger that don't have it.
I agree with spoulson. C# is really good at solving business problems. You can very effective create a framework that models your business processes and solve many of those problems with object orientation and design patterns. In that respect it provides much of the nice object oriented capability that C++ has.
If you are concerned with speed, C is the route to go for the reasons that you stated.
Further on the second question: you can run NGEN to generate a native image of the assembly, which can improve performance. Not quite machine code, but since it bypasses the JIT (just-in-time compile) phase, the app will tend to run much faster.
http://msdn.microsoft.com/en-us/library/6t9t5wcf(VS.80).aspx
The Native Image Generator (Ngen.exe)
is a tool that improves the
performance of managed applications.
Ngen.exe creates native images, which
are files containing compiled
processor-specific machine code, and
installs them into the native image
cache on the local computer. The
runtime can use native images from the
cache instead of using the
just-in-time (JIT) compiler to compile
the original assembly.
"is there some other reason then top
speed, to use any other language than
C#?"
I can think of at least four, all somewhat related:
I have a a large current investment in 'language X', and I don't have the time or money to switch to something else. (Port an existing code base, buy/acquire/port libraries, re-develop team skills in C#, learn different tools.)
An anticipated need to port the code to a platform where C# is not supported.
I need to use tools that are not available in C#, or are not as well supported. (IDE's, alternate compilers, code generators, libraries, the list goes on and on...)
I've found a language that's even more productive. ;-)
"what is the advantage of compiling
into CIL, and than run by CLR, than
directly compile it into machine
code?"
It's all about giving the runtime environment more control over the way the code executes. If you compile to machien code, a lot becomes 'set in stone' at that time. Deferring compilation to machine code until you know more about the runtime environment lets you optimize in ways you might not be able to otherwise. Just a few off the top of my head:
Deferring compilation lets you select instructions that more closely match your host CPU. (To use 64-bit native instructions when you have them, or the latest SSE extensions.)
Deferring code lets you optimize in ways you might not be able to otherwise. (If you have only one class at runtime that's derived from a specific interface, you can start to inline even virtual methods, etc.)
Garbage collectors sometimes need to insert checkpoints into user code. Deferring compilation lets the GC have more control and flexibility over how that's done.
First answer: C# should be used by default for new projects. There are a few cases where it hasn't caught up yet to C++ (in terms of multi-paradign support), but it is heading in that direction.
Second answer: "portability" also includes x86 / x64 portability, which can be achieved by setting the platform to AnyCPU. Another (more theoretical at this point) advantage is that the JIT compiler can take advantage of the CPU-specific instruction set and thus optimize more effectively.
Related
Background
I am developing a library called Harmony that currently uses detouring at the assembler level to monkey patch methods at runtime. This works fine and I got this to work on all combinations of hardware and .NET but it is sort of an ugly hack that does not work when methods are inlined.
Scope
I know roughly about the profiler API and that you can alter the IL before it reaches the JITer. My library already provides a high level way to get the modified IL body so all I need to do is to use the profiler API.
Asking around it was recommended to write small C/C++ modules accessing it but I rather would want to do this from my managed code. Reasons: my library should only be one final dll, I rather not want to deal with C/C++ code, different environments might make this hard.
Question
Is this approach possible? Is there an easier way? Is there a profiler library that hides this implementation and just gives me a high level replacement callback?
Note
Please do not question the motives of my library, I am fully aware that this falls outside of any “normal” C# programming. It’s mainly for patching and modding games and so far with 1500+ stars on GitHub a very successful project. I just want to lift it to an even more compatible level.
For a large application written in C++ using Visual Studio 6, what is the best way to move into the modern era?
I'd like to take an incremental approach where we slowly move portions of the code and write new features into C# for example and compile that into a library or dll that can be referenced from the legacy application.
Is this possible and what is the best way to do it?
Edit: At this point we are limited to the Express editions which I believe don't allow use of the MFC libraries which are heavily used in our current app. It's also quite a large app with a lot of hardware dependencies so I don't think a wholesale migration is in the cards.
Edit2: We've looked into writing COM-wrapped components in C# but having no COM experience this is scary and complicated. Is it possible to generate a C# dll with a straight-C interface with all the managed goodness hidden inside? Or is COM a necessary evil?
I'd like to take an incremental
approach where we slowly move portions
of the code
That's the only realistic way to do it.
First, what kind of version control do you use? (If you use branching version control that allows you to make experiments and see what works, while minimizing the risk of compromising your code; others are OK also, but you'll have to be really careful depending on what you are using).
Edit: I just saw you are using SVN. It may be worthwile to move to mercurial or git if you have the liberty to do that (the change provides a quantum leap in what you can do with the code-base).
and write new features into C# for
example and compile that into a
library or dll that can be referenced
from the legacy application.
That's ... not necessarily a good idea. C# code can expose COM interfaces that are accessible in C++. Writing client code in C++ for modules written in C# can be fun, but you may find it taxing (in terms of effort to benefits ratio); It is also slow and error-prone (compared to writing C# client code for modules written in C++).
Better consider creating an application framework in C# and using modules (already) written in C++ for the core functionality.
Is this possible and what is the best
way to do it?
Yes, it's possible.
How many people are involved in the project?
If there are many, the best way would be to have a few (two? four?) work on the new application framework and have the rest continue as usual.
If there are few, you can consider having either a person in charge of this, or more people working part-time on it.
The percentage of people/effort assigned on each (old code maintenance and new code development) should depend on the size of the team and your priorities (Is the transition a low priority issue? Is it necessary to be finished by a given date?)
The best way to do this would be to start adapting modules of the code to be usable in multiple scenarios (with both the old code and the new one) and continue development in parallel (again, this would be greatly eased by using a branching distributed version control system).
Here's how I would go about it (iterative development, with small steps and lots of validity checks in between):
Pick a functional module (something that is not GUI-related) in the old code-base.
Remove MFC code (and other libraries not available in VS2010 Express - like ATL) references from the module picked in step 1.
Do not attempt to rewrite MFC/ATL functionality with custom code, unless for small changes (that is, it is not feasible to decide to create your own GUI framework, but it is OK to decide to write your own COM interface pointer wrapper similar to ATL's CComPtr).
If the code is heavily dependent on a library, better separate it as much as possible, then mark it down to be rewritten at a future point using new technologies. Either way, for a library heavily-dependent on MFC you're better off rewriting the code using something else (C#?).
reduce coupling with the chosen module as much as possible (make sure the code is in a separate library, decide clearly what functionality the module exposes to client code) and access the delimited functionality only through the decided exposed interface (in the old code).
Make sure the old code base still works with the modified module (test - eventually automate the testing for this module) - this is critical if you need to still stay in the market until you can ship the new version.
While maintaining the current application, start a new project (C# based?) that implements the GUI and other parts you need to modernize (like the parts heavily-dependent on MFC). This should be a thin-layer application, preferably agnostic of the business logic (which should remain in the legacy code as much as possible).
Depending on what the old code does and the interfaces you define, it may make sense to use C++/CLI instead of C# for parts of the code (it can work with native C++ pointers and managed code, allowing you to make an easy transition when comunicating between managed .NET code and C++ native code).
Make the new application use the module picked in step 1.
Pick a new module, go back to step 2.
Advantages:
refactoring will be performed (necessary for the separation of modules)
at the end you should have a battery of tests for your functional modules (if you do not already).
you still have something to ship in between.
A few notes:
If you do not use a distributed branching version control system, you're better off working on one module at a time. If you use branching/distributed source control, you can distribute different modules to different team members, and centralize the changes every time something new has been ported.
It is very important that each step is clearly delimited (so that you can roll back your changes to the last stable version, try new things and so on). This is another issue that is difficult with SVN and easy with Mercurial / Git.
Before starting, change the names of all your project files to have a .2005.vcproj extension, and do the same for the solution file. When creating the new project file, do the same with .2010.vcxproj for the project files and solution (you should still do this if you convert the solutions/projects). The idea is that you should have both in parallel and open whichever you want at any point. You shouldn't have to make a source-tree update to a different label/tag/date in source control just to switch IDEs.
Edit2: We've looked into writing
COM-wrapped components in C# but
having no COM experience this is scary
and complicated.
You can still do it, by writing wrapper code (a small templated smart pointer class for COM interfaces wouldn't go amiss for example - similar to CComPtr in ATL). If you isolated the COM code behind some wrappers you could write client code (agnostic of COM) with (almost) no problems.
Is it possible to generate a C# dll
with a straight-C interface with all
the managed goodness hidden inside? Or
is COM a necessary evil?
Not that I know of. I think COM will be a necessary evil if you plan to use server code written in C# and client code in C++.
It is possible the other way around.
Faced with the same task, my strategy would be something like:
Identify what we hope to gain by moving to 2010 development - it could be
improved quality assurance: unit testing, mocking are part of modern development tools
slicker UI: WPF provides a modern look and feel.
productivity: in some areas, .NET development is more productive than C++ development
support: new tools are supported with improvements and bugfixes.
Identify which parts of the system will not gain from being moved to C#:
hardware access, low-level algorithmic code
pretty much most bespoke non-UI working code - no point throwing it out if it already works
Identify which parts of the system need to be migrated to c#. For these parts, ensure that the current implementation in C++ is decoupled and modular so that those parts can be swapped out. If the app is a monolith, then considerable work will be needed refactoring the app so that it can be broken up and select pieces reimplemented in c#. (It is possible to refactor nothing, instead just focus on implementing new application functionality in c#.)
Now that you've identified which parts will remain in C++ and which parts will be implemented in c#, (or just stipulate that new features are in c#) then focus turns to how to integrate c# and c++ into a single solution
use COM wrappers - if your existing C++ project makes good use of OO, this is often not as difficult as it may seem. With MSVC 6 you can use the ATL classes to expose your classes as COM components.
Integrate directly the native and c# code. Integrating "legacy" compiled code requires an intermediate DLL - see here for details.
Mixing the MFC UI and c# UI is probably not achieveable, and not adviseable either as it would produce a UI mix of two distinct styles (1990s grey and 2010 vibe). It is simpler to focus on achieving incremental migration, such as implementing new application code in c# and calling that from the native C++ code. This keeps the amount of migrated c# code small to begin with. As you get more into the 2010 development, you can then take the larger chunks that cannot be migrated incrementally, such as the UI.
First, your definition of modern era is controversial. There's no reason to assume C# is better in any sense than C++. A lot has been said on whether C# helps you better avoid memory management errors, but this is hardly so with modern facilities in C++, and, it's very easy to do mess with C# in terms of resource acquisition timing, that may be dependent on what other programs are doing.
If you move straight from 6 to 2010 you may end up with some messed up project settings. If this isn't a fairly large project, and it's one of few that you need to convert, then that should be fine. Just open it in 2010, and follow the conversion wizard. Make sure to back up your project first, and verify your project settings when you're done.
In my opinion though the best way is to convert it step by step through each iteration of Visual Studio. I had to modernize 1400 projects from 2003 to 2010, and the best way that I found was to convert everything to 2005, then to 2008, and then finally to 2010. This caused the least amount of issues to arise for me.
If you only have 6 and the newest Visual Studio you may end up just having to try and go straight to the new one using the wizard. Expect some manual cleanup before everything builds correctly for you again.
Also, one more time, BACK IT UP FIRST! :)
High-level C++ code calling low-level C# code doesn't look like a good idea. The areas where .NET languages are better, are user interface, database access, networking, XML files handling. Low-level stuff like calculations, hardware access etc. is better to keep as native C++ code.
Moving to .NET, in most cases it is better to rewrite UI completely, using WPF or Windows Forms technologies. Low-level stuff remains native, and different interoperability technologies are used to connect C# and native code: PInvoke, C++/CLI wrappers or COM interoperability. After some time, you may decide to rewrite low-level native components in C#, only if it is really necessary.
About compiling native C++ code in VS2010 - I don't see any problems. Just fix all compilation errors - new compilers have more strict type checking and syntax restrictions, and catch much more bugs at compilation time.
Not sure why so many folks are advocating for COM. If you haven't already got a lot of COM in there, learning how to do it on the C++ side is going to hurt, and then you're using the slowest possible interop from the managed side. Not my first choice.
Ideally you have refactored your UI from your business logic. You can then build a new UI (WPF, WinForms, ASP.NET, web services that support some other client, whatever) and call into your business logic through P/Invoke or by writing a C++/CLI wrapper. #mdma has good advice for you assuming that the refactoring is possible.
However if you were paying me to come in and help you my very first question would be why do you want to do this? Some clients say they don't want to pay C++ devs any more, so they want all the C++ code gone. This is a scary objective because we all hate to touch code that works. Some clients want to expose their logic to ASP.NET or Reporting Services or something, so for them we concentrate on the refactoring. And some say "it looks so 1999" and for them I show them what MFC looks like now. Colours, skinning/theming including office and win7 looks, ribbon, floating/docking panes and windows, Windows 7 taskbar integration ... if you just want to look different, take a look at MFC in VS 2010 and you might not have to adjust any code at all.
Finally to make non-Express versions of VS 2010 affordable look into the Microsoft Partner Program. If you have sold your software to at least 3 customers who still speak to you, and can get through the Windows 7 logo self test (I have got VB 6 apps through that in a day or two) then you can have 5-10 copies of everything (Windows, Office, VS) for $1900 or so a year, depending on where you live.
To start I'd try and keep as much code as possible to avoid a rewrite. I'd also remove all unused code before starting the conversion.
Since VC++ 6.0 Microsoft changed the MFC libraries and the C++ Standard Library.
I recommend to start building your DLLs with no dependencies, then looking at your third party libraries, and then rebuild one dependent DLL/EXE at a time.
Introduce unit tests to make sure the behaviour of code does not change.
If you have a mixed build, using different versions of VC++, you need to guard against passing resources (file handles) between DLLs that use different versions of the VC runtime.
If at all financially possible I would strongly consider just paying the money for the version of Visual Studio that you need because you could very well lose more money on the time you spend. I do not know enough about the express editions to give a good answer on them but when integrating some code from a subcontractor that was written in C++ I used C++ / CLI. You will probably be able to reuse most of your codebase and will be familiar with the language but you will also have access to managed code and libraries. Also if you want to start writing new code in C# you can do that. The biggest problem I had with it was that in VS 2010 there is no intellisense in C++ / CLI.
Visual Studio 6 is legendary for being buggy and slow. Moving into the modern era would best be done by getting a new compiler. What is probably the easiest thing to do is write the legacy app into a DLL, then write your exe into C# and use P/Invoke. Then you never have to touch the old code again- you can just write more and more in C# and use less and less of the old DLL.
If your old code is very heavily OO, you can use C++/CLI to write wrapper classes that allow .NET to call methods on C++ objects, and collect them too if you use a reference counted smart pointer.
You can use C# to write your new components with a COM or COM+ (System.EnterpriseServices) wrapper, which will be callable from your existing C++ code.
Which areas of programming are each language best suited for?
I like both C++ and C# but i prefer to use C# because of .NET.
My question is when will you use C++ and when do you use C#?
So if you make a financial application for a company you will use C#? ( It's easy to design a form and connect to a database without downloading 3rd party libraries, and if you make advanced algorithms you would use C++ for it's speed?
This is my idea. I just watched video's # http://www.academicearth.org, and it seems that universities prefer to use C++ for Machine Learning for example.
What do you guys think of it? and what is the industry view on this.
Trying to compare the two isn't really fair -- C++ is usually used nowadays when you have the need for low-level, or portable, high performance code. You rarely find it used to implement business logic for enterprise systems, though about 10 years ago you did. You certainly wouldn't want to start out development with an enterprise system with C++ today unless you had a really, really good reason to.
But in academia, C and C++ have been used for many years, so it's probably not surprising that there is a large base of C++ code there for things like Machine Learning. C++ can often be faster than C# when it's optimized properly. It can run with less memory, on more platforms, and with fewer dependencies on large frameworks than C# can.
C#, however, is a lot more forgiving with its memory model, and typically has access to Microsoft or Mono's very large, comprehensive framework which allows developers to do a lot of stuff with minimal development effort, time, and cost. If you're working on the Microsoft platform, it is arguably the standard language nowadays.
Always use C# for business solutions. It's a more evolved language.
I worked for a company that does real-time authentication for PPV (like if you buy WWE or boxing on cable). They have huge volume right before the event. The team that worked on that part insisted that it had to be written in C++ for speed.
After a year of debating, we finally wrote a prototype replacement in C#. It turned out that the replacement was twice as fast.
There are VERY few problem domains where you need any of the optimizations you can do in C++ that are unavailable in C#, but C# code is much less error prone.
Often we will use C# for front-end UI development, and C++ for server-side. One of the main reasons is portability/speed. People tell me mono for C# on linux/OSX is fast and stable, but from what I have seen that is not the case. YMMV.
The one feature I like in C++ is the low-level access to memory and the control over memory-layout of structures. If you interface with even lower level APIs such as OpenGL, you usually interact with arrays of basic datatypes, such as floats. In C++, you can cast a void* texture to user defined types such as Image2D<PixelWithAlphaChannel<float, 4> > and use a fully object oriented interface for this otherwise unstructured dump of unspecified data.
If you cannot afford to keep multiple copies of low-level API data, C++ is the way to keep your code clean. However, you trade a lot of developer time for this. While in theory C++ allows for faster code (or at least the same speed, you could implement .NET in C++, but not vice versa), having tools such as Resharper and dotTrace can enable developers to improve the performance faster. So in practice, I'd opt for C# for both financial applications AND performance critical algorithms, IF they are not constrained by low-level APIs.
From a commercial and support perspective, C# is still a one platform wonder. If you're not targetting the .NET runtime then it's not usually a realistic choice to use C#.
C++ is supported by a huge array of platforms, from embedded OS's to super-computers.
If you're targetting .NET, then C# is probably a more suitable language, there isn't really a good binding for C++, C++/CLI is more like a different or extended language in any case.
If there is a genuine choice, then the most overriding consideration should be the expertise available. Getting a bunch of C++ experts to develop in C# is a poor use of skills; writing a system in C++ with no C++ experts will probably result in a mess.
I learned windows programming using Visual C++, and the Win32 API. Nowadays, it seems most apps are being developed in .NET using C#. I understand that most of the time there isn't much performance difference between native code and managed code. So I'm wondering, if I were to start writing a new desktop app today, is there any reason (other than the fact that I'm more familiar with C++), that I might want to write it in non-managed C++ instead of .NET? Are there still some advantages to using C++ and native code? Or has that method been more-or-less replaced with .NET on the Windows platform?
Of course I know that people who are writing low-level device drivers and similar programs wouldn't do it in .NET. I'm asking with reference to typical client-facing apps that don't make direct hardware calls.
IMO the most important one for small downloadable applications is that native code does not need the .NET runtime. While broadband becomes more and more common not nearly everybody has it yet.
Some people may be disappointed to see that your 2 MB application actually requires another 20MB of framework download and a bothersome installation process to run. If they are not sure whether or not they really need your application in the first place, they might just delete it before even giving it a try and turn to a competing product.
Performance (certain situations, such as graphics)
Memory footprint (as Mancuso said)
Use of existing libraries
No need for a runtime
Finer control
To list a few.
However, you may also want to look at the question from the opposite angle to fairly evaluate which language to use.
Additionally, you could use C++/CLI to incorporate both native and .net code.
If your application needs to be able to run without an installation (i.e. if you can't or shouldn't do something like install the .NET framework), you can't count on .NET being on a windows machine (pre-Vista). Lots of utility applications can fall in this category.
I would recommend to write every desktop application in managed code. .NET/C# is a great platform to do so.
My reasons:
Performance penalty is negligible. Google for benchmarks if you don't take my word. What matters more is the code itself. You can write O(n^m) algorithms in C++ or .NET/C#. JIT engines are very mature these days.
Unmanaged C++ has major drawbacks when it comes to unit testing, mocking and refactoring. It's very cumbersome and inflexible. Reflection allows managed code to make such things very convenient.
Deployment is a small issue. However, creating a setup which checks for the necessary .NET preconditions and installs them automatically is a no-brainer.
Compilation is quicker, no linker! It even happens in the background when you edit the code.
.NET library support is way better and cleaner than STL, MFC and boost.
No header files and macros. They are just error prone.
Security! Good bye buffer overflows, bad pointers, uninitialized variables...
Exceptions. Clear exception hierarchy in .NET. C++ exceptions are messed up.
Memory footprint. But unless you're developing for a severely handicapped machine memory-wise, it really shouldn't be an issue for most applications.
If you can afford the dependency on the stack, go for .NET
Modern, elegant, powerful and as a result much quicker to develop for.
But realize that you chain your app to it - to the language and the framework, if you forsee a future where you may want to escape this, then better think twice.
Win32 is old and clunky, but it works on virtually any Windows version without extra dependencies, and your code can be in plain, portable, C/C++.
+1 for not having to require a .NET package/install on the target machine(s). This is still a big issue.
When all machines have mono or NET it won't be such a big deal.
Two things that I can think of.
Protection of intellectual property. It's infinitely harder for someone to reverse engineer an Unmanaged C++ app. Managed .Net or Java apps can be easily de-compiled this is not the case with Unmanaged C++.
Speed. C++ is closer to hardware and has a smaller memory footprint as the other comment mentioned. This is why most video games continue to be written in C++ and inline assembly.
.Net programs also have a support lifetime, where native do not really. Native will run for many years across different OS's without requiring updates.
.Net programs can be hosed by bad .Net configuration, native just keeps on running and is hardly effected by OS updates.
.Net programs startup slow and feel sluggish, native starts quick and runs quick.
.Net has to be coded for lowest common denominator (most distributed framework version), Native compiles all code into application - so use what you want.
Use Delphi for Native, not C++. .Net is partially based on Delphi RAD and Java backend.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
As I posted earlier here I've decided to try my hand at one of these, but given my interests as a web developer, I'd like to know the difference between them in their real-world applications.
Edit Note:
While I'm a web developer, please don't let that limit your answer. I'm 30...I've got years of career changing ahead of me.
Bear in mind that I speak ASFAC++B. :) I've put the most important differentiating factor first.
Garbage Collection
Garbage Collection (GC) is the single most important factor in differentiating between these languages.
While C and C++ can be used with GC, it is a bolted-on afterthought and cannot be made to work as well (the best known is here) - it has to be "conservative" which means that it cannot collect all unused memory.
C# is designed from the ground up to work on a GC platform, with standard libraries also designed that way. It makes an absolutely fundamental difference to developer productivity that has to be experienced to be believed.
There is a belief widespread among C/C++ users that GC equates with "bad performance". But this is out-of-date folklore (even the Boehm collector on C/C++ performs much better than most people expect it to). The typical fear is of "long pauses" where the program stops so the GC can do some work. But in reality these long pauses happen with non-GC programs, because they run on top of a virtual memory system, which occasionally interrupts to move data between physical memory and disk.
There is also widespread belief that GC can be replaced with shared_ptr, but it can't; the irony is that in a multi-threaded program, shared_ptr is slower than a GC-based system.
There are environments that are so frugal that GC isn't practical - but these are increasingly rare. Cell phones typically have GC. The CLR's GC that C# typically runs on appears to be state-of-the-art.
Since adopting C# about 18 months ago I've gone through several phases of pure performance tuning with a profiler, and the GC is so efficient that it is practically invisible during the operation of the program.
GC is not a panacea, it doesn't solve all programming problems, it only really cleans up memory allocation, if you're allocating very large memory blocks then you will still need to take some care, and it is still possible to have what amounts to a memory leak in a sufficiently complex program - and yet, the effect of GC on productivity makes it a pretty close approximation to a panacea!
Undefined Behaviour
C++ is founded on the notion of undefined behaviour. That is, the language specification defines the outcome of certain narrowly defined usages of language features, and describes all other usages as causing undefined behaviour, meaning in principle that the operation could have any outcome at all (in practice this means hard-to-diagnose bugs involving apparently non-deterministic corruption of data).
Almost everything about C++ touches on undefined behaviour. Even very nice forthcoming features like lambda expressions can easily be used as convenient way to corrupt the stack (capture a local by reference, allow the lambda instance to outlive the local).
C# is founded on the principle that all possible operations should have defined behaviour. The worst that can happen is an exception is thrown. This completely changes the experience of software construction.
(There's unsafe mode, which has pointers and therefore undefined behaviour, but that is strongly discouraged for general use - think of it as analogous to embedded assembly language.)
Complexity
In terms of complexity, C++ has to be singled out, especially if we consider the very-soon-to-be standardized new version. C++ does absolutely everything it can to make itself effective, short of assuming GC, and as a result it has an awesome learning curve. The language designers excuse much of this by saying "Those features are only for library authors, not ordinary users" - but to be truly effective in any language, you need to build your code as reusable libraries. So you can't escape.
On the positive side, C++ is so complex, it's like a playground for nerds! I can assure you that you would have a lot of fun learning how it all fits together. But I can't seriously recommend it as a basis for productive new work (oh, the wasted years...) on mainstream platforms.
C keeps the language simple (simple in the sense of "the compiler is easy to write"), but this makes the coding techniques more arcane.
Note that not all new language features equate with added complexity. Some language features are described as "syntactic sugar", because they are shorthand that the compiler expands for you. This is a good way to think of a great deal of the enhancements to C# over recent years. The language standard even specifies some features by giving the translation to longhand, e.g. using statement expands into try/finally.
At one point, it was possible to think of C++ templates in the same way. But they've since become so powerful that they are now form the basis of a whole separate dimension of the language, with its own enthusiastic user communities and idioms.
Libraries
The strangest thing about C and C++ is that they don't have a standard interchangeable form of pre-compiled library. Integrating someone else's code into your project is always a little fiddly, with obscure decisions to be made about how you'll be linking to it.
Also, the standard library is extremely basic - C++ has a complete set of data structures and a way of representing strings (std::string), but that's still minimal. Is there a standard way of finding a list of files in a directory? Amazingly, no! Is there standard library support for parsing or generating XML? No. What about accessing databases? Be serious! Writing a web site back-end? Are you crazy? etc.
So you have to go hunting further afield. For XML, try Xerces. But does it use std::string to represent strings? Of course not!
And do all these third-party libraries have their own bizarre customs for naming classes and functions? You betcha!
The situation in C# couldn't be more different; the fundamentals were in place from the start, so everything inter-operates beautifully (and because the fundamentals are supplied by the CLR, there is cross-language support).
It's not all perfect; generics should have been in place from the start but wasn't, which does leave a visible scar on some older libraries; but it is usually trivial to fix this externally. Also a number of popular libraries are ported from Java, which isn't as good a fit as it first appears.
Closures (Anonymous Methods with Local Variable Capture)
Java and C are practically the last remaining mainstream languages to lack closures, and libraries can be designed and used much more neatly with them than without (this is one reason why ported Java libraries sometimes seem clunky to a C# user).
The amusing thing about C++ is that its standard library was designed as if closures were available in the language (container types, <algorithm>, <functional>). Then ten years went by, and now they're finally being added! They will have a huge impact (although, as noted above, they leak underfined behaviour).
C# and JavaScript are the most widely used languages in which closures are "idiomatically established". (The major difference between those languages being that C# is statically typed while JavaScript is dynamically typed).
Platform Support
I've put this last only because it doesn't appear to differentiate these languages as much as you might think. All these languages can run on multiple OSes and machine architectures. C is the most widely-supported, then C++, and finally C# (although C# can be used on most major platforms thanks to an open source implementation called Mono).
My experience of porting C++ programs between Windows and various Unix flavours was unpleasant. I've never tried porting anything very complex in C# to Mono, so I can't comment on that.
Both C and C++ give you a lower level of abstraction that, with increased complexity, provides a breadth of access to underlying machine functionality that are not necessarily exposed with other languages. Compared to C, C++ adds the convenience of a fully object oriented language(reduced development time) which can, potentially, add an additional performance cost. In terms of real world applications, I see these languages applied in the following domains:
C
Kernel level software.
Hardware device drivers
Applications where access to old, stable code is required.
C,C++
Application or Server development where memory management needs to be fine tuned (and can't be left to generic garbage collection solutions).
Development environments that require access to libraries that do not interface well with more modern managed languages.
Although managed C++ can be used to access the .NET framework, it is not a seamless transition.
C# provides a managed memory model that adds a higher level of abstraction again. This level of abstraction adds convenience and improves development times, but complicates access to lower level APIs and makes specialized performance requirements problematic.
It is certainly possible to implement extremely high performance software in a managed memory environment, but awareness of the implications is essential.
The syntax of C# is certainly less demanding (and error prone) than C/C++ and has, for the initiated programmer, a shallower learning curve.
C#
Rapid client application development.
High performance Server development (StackOverflow for example) that benefits from the .NET framework.
Applications that require the benefits of the .NET framework in the language it was designed for.
Johannes Rössel makes the valid point that the use C# Pointers, Unsafe and Unchecked keywords break through the layer of abstraction upon which C# is built. I would emphasize that type of programming is the exception to most C# development scenarios and not a fundamental part of the language (as is the case with C/C++).
C is the bare-bones, simple, clean language that makes you do everything yourself. It doesn't hold your hand, it doesn't stop you from shooting yourself in the foot. But it has everything you need to do what you want.
C++ is C with classes added, and then a whole bunch of other things, and then some more stuff. It doesn't hold your hand, but it'll let you hold your own hand, with add-on GC, or RAII and smart-pointers. If there's something you want to accomplish, chances are there's a way to abuse the template system to give you a relatively easy syntax for it. (moreso with C++0x). This complexity also gives you the power to accidentally create a dozen instances of yourself and shoot them all in the foot.
C# is Microsoft's stab at improving on C++ and Java. Tons of syntactical features, but no where near the complexity of C++. It runs in a full managed environment, so memory management is done for you. It does let you "get dirty" and use unsafe code if you need to, but it's not the default, and you have to do some work to shoot yourself.
My opinion is C# and ASP.NET would be the best of the three for development that is web biased.
I doubt anyone writes new web apps in C or C++ anymore. It was done 10 years ago, and there's likely a lot of legacy code still in use, but they're not particularly well suited, there doesn't appear to be as much (ongoing) tool support, and they probably have a small active community that does web development (except perhaps for web server development). I wrote many website C++ COM objects back in the day, but C# is far more productive that there's no compelling reason to code C or C++ (in this context) unless you need to.
I do still write C++ if necessary, but it's typically for a small problem domain. e.g. communicating from C# via P/Invoke to old C-style dll's - doing some things that are downright clumsy in C# were a breeze to create a C++ COM object as a bridge.
The nice thing with C# is that you can also easily transfer into writing Windows and Console apps and stay in C#. With Mono you're also not limited to Windows (although you may be limited to which libraries you use).
Anyways this is all from a web-biased perspective. If you asked about embedded devices I'd say C or C++. You could argue none of these are suited for web development, but C#/ASP.NET is pretty slick, it works well, there are heaps of online resources, a huge community, and free dev tools.
So from a real-world perspective, picking only one of C#, C++ and C as requested, as a general rule, you're better to stick with C#.
C - an older programming language that is described as Hands-on. As the programmer you must tell the program to do everything. Also this language will let you do almost anything. It does not support object orriented code. Thus no classes.
C++ - an extention language per se of C. In C code ++ means increment 1. Thus C++ is better than C. It allows for highly controlled object orriented code. Once again a very hands on language that goes into MUCH detail.
C# - Full object orriented code resembling the style of C/C++ code. This is really closer to JAVA. C# is the latest version of the C style languages and is very good for developing web applications.
From your other posts, I guess you want to learn a new language to get new skills. My advice is that the language is not really important, what is important is the quality of its community (advice, but also existing code you can read and learn from) and the available libraries/frameworks. In this respect, I think the "C family" is not the best choice for you: web libraries and frameworks are few, not portable and not great, and coding style of code you can study varies a lot and may confuse you a lot (although C is my favorite language).
I would advise to just learn C, and try to really understand the concept of pointers, then move to other languages more adapted to the web (Python or JavaScript comes to mind - or even Java). Also, in the C family, Objective-C has the best mix of power and simplicity in my opinion, but is a niche player.
C is the core language that most closely resembles and directly translates into CPU machine code. CPUs follow instructions that move, add, logically combine, compare, jump, push and pop. C does exactly this using much easier syntax. If you study the disassembly, you can learn to write C code that is just as fast and compact as assembly. It is my preferred language on 8 bit micro controllers with limited memory. If you write a large PC program in C you will get into trouble because of its limited organization. That is where object oriented programming becomes powerful. The ability of C++ and C# classes to contain data and functions together enforces organization which in turn allows more complex operability over C. C++ was essential for quick processing in the past when CPUs only had one core. I am beginning to learn C# now. Its class only structure appears to enforce a higher degree of organization than C++ which should ultimately lead to faster development and promote code sharing. C# is not interpreted like VB. It is partially compiled at development time and then further translated at run time to become more platform friendly.
For raw speed, use C. For power, use C++. For .NET compatibility, use C#.
They're all pretty complex as languages go; C through decades of gradual accretion, C++ through years of more rapid enhancement, and C# through the power of Microsoft.