C# vs C++, .NET vs VS 6.0

Hi all,

I have been using and learning C++ for a number of years and have been wondering if C# is worth picking up. Anyone with experience with both C# and C++ care to comment on the differences between C++ and C#, and whether C# is worth the time?

Another related question is Visual Studio .NET. Is there any reason to upgrade from Visual Studio 6 to Visual Studio .NET, especially pertaining to MFC and Visual Basic?

Many thanks in advance!

I’m primarily a C++ coder who recently decided to do a project in C#, using VS.NET 2003.

I had my choice of languages to code in, and ultimately chose C# for my project because it offered a lot of the flexibility of C++, without a lot of the gotchas that you’re constantly worried about. I don’t have to remember to delete objects or close pointers; the environment picks that up for me. I can pass values by ref (ie, pass around pointers) but it’s not quite so raw as C++ is. IMO C# offers some of the simplicity of VB without the idiotic syntax (hey, I’m a C coder, VB is just not as elegant IMO) along with some (but not all) the power of C++.

Things I miss most are macros. I like wrapping up things like error checking in macros, and C# doesn’t support them. I also like #defining constants, and it doesn’t support that.

Things I don’t miss are having to have separate .h and .c files. C# uses one file to both declare and define methods and function. Scoping is easier too.

I’m not sure how C# would stand up to a really big project, but for what I’m doing (a GUI app with a DB backend) it’s significantly eased the development time.

RE: VS 6.0 vs VS .NET: .NET is a whole different beast. If you’re going to upgrade to .NET, I highly recommend that you read up on the .NET framework before diving in. The biggest difference is that all code compiled with .NET is compiled into a common runtime language that the .NET framework understands. Doesn’t matter if you use C#, C++, VB, etc. etc - it all ends up as the common runtime language.

There’s also some nice garbage collection built into the framework, and some other goodies that you’ll like. Like I said - if you’re looking at coding low level libraries or Windows services or stuff like that, I can’t vouch for how well .NET will do that. I still suspect that C/C++ is the language of choice for those types of apps. But for general Windows apps, GUIs, etc. I think .NET is an excellent choice. The editor alone is a joy to use. I picked up .NET with a big of trepidation, but I’m very happy with it now.

Personally, I am rather impressed (mostly) with how Microsoft set up their .NET architecture. I much prefer developing in VS .NET as opposed to 6.0.

In a nutshell, C# can be seen as Microsoft’s version of Java. The two languages are extremely similar, even to the point of cross-platform compatibility. Don’t get me wrong, Java still completely dominates in this area, but Microsoft seems to be working towards this goal little by little.

Here is a website that describes the basics in pretty good detail.

http://www.softsteel.co.uk/tutorials/cSharp/contents.html

Overall, if I am developing a visual application for Windows, I prefer C# over VC++, but for backend uses I still make use of the latter. In my opinion, VB.NET is considerably better than VB 6.0, as well.

Hope this helps.

LilShieste

Athena:

You never “have” to have separate .h and .c/.cpp files. Everything will work just fine if you put your declarations at the top of your .c/.cpp file.

Maybe you don’t technically have to separate .h and .cpp files, but it’s certainly been a code standard at every software house I’ve worked at. I’ve actually never seen a professionally developed C++ project that didn’t adhere to that standard.

If you’re a serious C++ programmer (i.e. you don’t use it like C with classes) the far more standards compliant C++ compiler is worth getting.

At the moment, C# is missing generics (templates), like Java. However, the next version of C# will include things like closures and generics, making a great language a lot better, IMO.

You don’t need to shell out for VS.NET, unless you really want to, or you’re going to be releasing commerical apps. The SDK is free from MS’s website, and Borland’s commercial C# IDE (C# Builder) is available free from their site for non-commercial usage.

LostCause you’ve using* C++ for years? you poor sod.

If you know a decent amount of C++ C# will be a breeze.

I never managed to pick up OO programming using C++, the horrible syntax got in the way of the concepts. I picked up the basic concepts learning some Java but I was exasperated by endless this method has been deprecated compiler messages - the #*$%ing language was (is?) constantly mutating. (And there are some boo-boos) how many objects do you need to open a text file for gawd’s sake!

C# seems to have learned from mistakes in Java. Finally I can write proper OO programs - hooray!

And the IDE is terrific.
*and learning, says it all really

The biggest reason, IMO, is you don’t have to use that godawful MFC anymore. You can drag controls around on a form, change their properties, and write code for their events, just like in Visual Basic, Delphi, C++Builder, etc. If you need to write a custom control, you can create it in .NET, load it into the IDE, and use it on a form just like a built-in control.

C# is a nice language, but Managed C++ (the .NET version of C++) is also good to have, especially if you need to interoperate with any non-.NET code you already have. MC++ is the only .NET language that lets you mix native and managed code in the same module, and it exposes some of the .NET runtime internals that aren’t available in the other .NET languages.

As far as the differences between C# and C++, the first ones you might notice are that all method code has to be written inside the class declaration (as in Java), and structs are more than just public classes - structs are value types, but classes are reference types. For example:


SomeType foo = new SomeType();
foo.x = 123;
SomeType bar = foo;
bar.x = 456;

// this will show "123" if SomeType is a struct, but "456" if it's a class
MessageBox.Show(foo.x);

But then if you want to use functions or types from File1.cpp in File2.cpp, you’ll have to copy the declarations into the new file… or go back to using a separate header.

Mr. 2001:

You’re 100% right about that. Separate .h and .cpp files are a convenience, not a burden. But Athena was saying that that’s a burden in C++, and I was pointing out that if she doesn’t like it, it can be dispensed with. (From a language perspective; obviously, some professional environments require it.)

Well, I think her point was that C# gives you the convenience of C++'s headers without actually needing a separate header file. You can just write your class in File1.cs and refer to it in File2.cs, and the compiler makes it work. (Delphi works similarly, but you have to divide your source files into “interface” and “implementation” parts, and explicitly add File1 to File2’s “uses” list.)

Some background: I’ve been a professional developer for 7 years, with most of that using C++ for development, with 6 months of C# experience. I use Perl and Python for scripting.

That said, what do you plan on using them for? C++ is a mature multi-paradigm language, whereas C# is a new OO language (basically Java with the serial numbers filed off). My personal opinion is that C# is a waste of time for any significant project. The primary advantage of C# is the GUI builder in VS.Net, and the .Net libraries (accessible by any .Net language). The libraries include threading, sockets, and regular expressions (to name a few items that I found handy). Similar libraries for C++ can be found in wxWindows and boost (and in my experience perform better).

We did find problems in the .Net regexp library, which was a serious problem until we found a workaround.

Basically, it’s nice to have everything in one nice neat package, but the plusses of C# were outweighed by the minuses for me. Some minuses:

  • generics missing (should be coming soon in .Net 2.0)
  • brain dead Dispose() model (see my usenet posting here)
  • properies: you never know whether you’re setting a value or calling a function
  • 80% of the stuff you need to do is easy, 20% is near impossible

If you can use VS.Net 2003, it is a massive improvement over VS6 for C++. It’s very close to the C++ standard (missing template export and exception specifications, but that’s it), though you’ll have to choose between class streams (like <iostream.h>) and standard streams (like <iostream>). I haven’t done any MFC work in VS.Net so I have no opinion on that.

What gotchas?

I don’t understand what this means. You can pass values by ref, const ref, pointer or const pointer in c++. What do you mean it’s “not quite so raw” as C++ is? Modern C++ (that is, since roughly 1998) techniques make manual memory management almost nonexistent.

Oh and this reminds me of another C# problem. Look up “boxing and unboxing”. That’s full of fun.

:eek: Macros are also heavily deemphasized in C++. No offense, but you appear to be more of a C programmer than a C++ programmer.

This is one of my big complaints in C#. Having the separate files means you can easily separate interface and implementation. By forcing you to have all implementation and declaration together, your class definition can have many lines of code separating functions.

This is precisely the kind of project that C# is well suited for.

Not true. C++ can be compiled to native code. Managed C++ must be compiled to CLI. Oh, and by way, if you distribute your application, be aware that it can be decompiled trivially.

It’s an improvement, but I’m a longtime VIM user, and find the editor to be a weakling. It is and improvement over the editor in version 6 though.

BTW, if you like the GUI builder and C++, but you don’t want to use .NET, check out Borland C++Builder.

That doesn’t really ring true to me… Dispose isn’t deterministic GC, it’s intended for releasing resources that can’t wait for a GC. Your .NET objects still take up memory until the GC decides to scrap them, but Dispose lets you close a file/socket or release other Windows resources before then.

The concept of ownership doesn’t really apply in a garbage collected environment. When you say “this object owns that one”, that’s shorthand for “when this object is deleted, it will delete that one in turn, and as long as this object exists, that one will too”. But when you have a garbage collector, objects can’t delete each other at all–only the GC can do that–and objects stick around as long as they’re needed.

When the first object’s Dispose method is called by the GC, it doesn’t matter that it isn’t allowed to dispose its “owned” objects, because the GC will dispose those too. And when you call the first object’s Dispose method before it’s garbage collected (which is the whole point of using Dispose, after all), it can dispose the others immediately.

IMO properties are a plus, not a minus (and you do know, if you check the documentation, the class browser, or the IDE tooltips ;)). You don’t have to know or care what happens internally when you read or write a button’s caption, it makes sense to think of the caption as a “value” instead of a pair of functions, and you get automatic design-time support for properties in the IDE.

If you think that’s fun, try it in MC++: You have to explicitly tell the compiler when to box, and decide whether you want to copy an object when you unbox it, or just use it while it’s still boxed.

That said, I think having a single root class for all types is a great concept, and boxing is a decent compromise to make value types behave like objects when you need them to (e.g. to put them in an list with mixed types), without the overhead of tossing around an object during the 95% of the time when you just want an integer to be an integer. The C# unboxing syntax is just like any other dynamic cast.

That’s why the editor lets you collapse and expand blocks of code. :slight_smile:

(What, you want to use a third-party editor? This is MS we’re talking about.)

No, it is most certainly not shorthand for deletion. It means control of object lifetime. At the end of its lifetime it releases all resources and may affect global state. Memory is only one resource. Others include file handles, OpenGL contexts (and display lists, textures, etc.), UI widgets, sockets, and database connections to name a few.

Nondeterministic GC robs you of the ability to gracefully control object lifetime. Fortunately, Herb Sutter (C++ guru) is working at MS on some extensions to Managed C++ to have GC and lifetime control. I don’t agree with all of his reasoning, but I think it’s an improvement, and will make Managed C++ the best .Net language.

Without that control, it’s very hard to make a robust library.

Which means that when you see Object_Instance.value you don’t know if it’s a quick or a lengthy operation. I seem to recall some library “properties” which had significant latency. Had the syntax been Object_Instance.value(), it would have been obvious that something was going on. Even worse, if the member changes from a simple member to a property there is no indication that semantics have changed.

But really only necessary if you don’t have generics. C# design decisions shifted many compile-time errors in C++ to runtime errors in C#. Not exactly an improvement in my book.

My editor does that just fine (it’s called “folding” generally). But it’s a mess in the VS editor. I prefer my editor allowing me to fold wherever I choose, rather than telling me where I have to fold.

Additionally, from what I’ve seen in the few C# shops I know of, the autocompletion really encourages “programming by guessing”. Also not an improvement (though, to be fair, developers who guess are going to get into trouble with or without such tools).

They want to make Windows the best platform for end users and for developers. Providing an SDK for editors would make a lot of developers happier (not just VIMmers like me, but Emacs users and Slickedit users, etc. as well).

There are two types of programming projects I am into right now. One is GUI-intensive applications, basically utilty tools that manages datas & information and etc. I have been trying to pick up VB 6.0 for that.

The other type of programming I am into is basically games (SDL, OpenGL). I afraid for that I would have to stick to C++.

I am intrigued by the common .NET framework. Can I just pop into .NET with my current knowledge of C++, still using stdio and etc. without learning new concepts? Is programming Windows with .NET with C++ possible? Or does it have to be C#?

Development-time wise, which is faster, VB or C# or MFC (whatever they use now in .NET)?

With Dispose(), you can take care of all of those except memory (and anyone who needs precise control over when memory is freed should stay away from .NET for now). C#'s “using” syntax makes disposal automatic, and you can do something similar in MC++ with templates.

Seems to me you should be upset with the programmers for putting lengthy operations in their property getters, not the language simply for having properties as an option. If the language didn’t have properties, you’d have to write Object_Instance.value() every time you fetched something like a button’s caption, and you still wouldn’t know whether it’s a quick or lengthy operation because you’d be using it all the time.

You could optimize that by using a public member variable instead of accessor functions when possible, but (1) it’d require programmers to use different syntax for different “properties” of your class, depending on how you chose to implement them, not on any logical aspect of the properties themselves, (2) you’d have to be absolutely sure that a future version or a derived class wouldn’t need an accessor function for that property, and (3) the IDE, COM interop, and other classes wouldn’t be able to easily get a list of your class’s properties.

Not quite. Generics won’t help you mix types like this:

String.Format("{0}'s account balance at {1} is ${2}", “John Smith”, johnsBankObject, 1680.55)

The VS editor lets you fold wherever you choose, last time I checked: Highlight a block of code, right-click, and tell it to collapse. Or (in C#) use #region to mark areas that should be foldable.

Well, you can compile C++ projects as managed code, technically making them .NET applications, but to take advantage of the .NET Framework or use any other .NET classes, you’ll have to learn new concepts.

You can still use stdio, STL, and other C++ libraries from MC++.

You can use Managed C++ to make .NET apps. The syntax will be familiar, but there are plenty of new concepts and ugly new keywords to learn.

Besides MC++ and C#, there’s also VB.NET (which, from what I’ve heard, is as different from regular VB as MC++ is from C++) and some third party compilers: Delphi for .NET, Fortran for .NET, COBOL for .NET, etc.

MFC is only for native apps, and in my experience it’s horribly slow to make any GUI-intensive program with MFC. MFC seems to be designed for writing Microsoft Office, and not much else. :wink:

VB.NET and C# are about the same. MC++ will probably take a little longer, since it’s lower level and more verbose. But if you have to interoperate with any existing native code, you’ll probably find it much faster to write those parts in MC++.

I strongly suggest using C# for this instead. C# is clearly MS’s favored son for .Net programming.

In those cases I would suggest using VS.Net 2003 (what most people call 7.1) just for the more conforming compiler. However, if you’re using SDL that suggests you’re going for some cross-platform compatibility, and many of the compilers on other platforms aren’t conforming yet (notable gcc). Also, libraries like SDL (which have had to work around problems with VC++6.0) may not compile under 7.1 (I don’t know in SDL’s case), so 6.0 may be more cross-platform compatible than 7.1.

.Net is the CLI (like the bytecode of Java) and the libraries. If you compile C++ to native code, it’s not .Net and you can’t use the libraries. You can use Managed C++ to compile C++ to the CLI and use the libraries, but the syntax is pretty nasty from what I’ve seen (but I’ve never used it).

I would say that C# beats MFC for most things, but at least with MFC if there is a shortcoming, you can get handles to the Windows C API and do some dirty work. However with C# if you can’t do something, you’re (AFAIK) just plain stuck.

Not really. You can use Platform Invoke from any .NET language to call Windows API functions, or almost any other function in a native DLL. If you use MC++, then you can also call API functions directly from managed code, just as you would in regular C++.

Again, I’m not concerned about precise control about memory. I’m concerned about precise control over object lifetime, which can affect things like other resources and program state.

Manual Dispose() is fine if you want to release a single object owned by a single owner. But if the object is shared, you can’t do it as easily, so it does make sense for a GC engine to deal with it–but because you can’t count on deterministic GC you don’t know if the sub-objects are being disposed of before the parent object. You basically have to implement your own reference-counted Dispose().

C++ has the RAII (Resource Acquisition Is Initialization) idiom which deals with this quite well. Sutter’s proposed solution would allow deterministic destruction, but non-deterministic memory reclamation. I think it’s the best thing I’ve seen so far.

[quote]
Seems to me you should be upset with the programmers for putting lengthy operations in their property getters, not the language simply for having properties as an option./quote]The programmers I’ve seen who’ve abused this are MS programmers and the .Net library. So it’s the same group of people anyway.

But you do know that it’s a nontrivial operation. And you can check the documentation to see what the operation is. But if there is no function call, you are guaranteed a trivial operation.

I guess you aren’t familiar with C++ streams:

os << “John Smith” << “'s account balance at " << johnsBankObject << " is $” << 1680.55;

Or, boost formatter:

os << boost::format("%0%'s account balance at %1% is $%2%") % “John Smith” % johnsBankObject % 1680.55;

Or (as I use):

string s = Format( “%s’s account balance at %t is $%0.2f” ) << “John Smith” << johnsBankObject << 1680.55;

Which keeps things as concise as printf but is typesafe as well. All of this uses C++ templates. If C# generics can’t do this, then I’m unimpressed.

Another problem with (at least the CLI implementation) is that every object has a ToString function. Which can cause some confusion. If you format an Enum to a string, you don’t get the value of the Enum, you get it’s name. So basically there’s an implicit cast from Enum to string, but not from Enum to int (in C++ of course, enum’s have an implicit cast to int, but int does not have an implicit cast to an enum).

Either that wasn’t the case in .Net 2002 (where I spent most of my time) or I didn’t notice it. Thanks for correcting me.

I can’t believe I forgot to comment on using. IMO just a big band-aid. The syntax is clumsy, adds an unnecessary scope and, overloads the term “using”, and it doesn’t proect you against double Dispose().

Java (9 years ago!) used the syntax intance=0 to mean that if this was the last reference, finalize it now. There is no concept like this in C#. “Using” is an ugly hack.