learn C++ or C#

  • Thread starter Thread starter Daniel
  • Start date Start date
[David Wilkinson]
Fortunately most of my consulting work is cross-platform non-GUI C++, si I
do not need to worry about this. The code is developed in Visual Studio,
but runs as a console application in various linux/Unix systems, as well
as Windows. My client also wraps it in C++/CLI for Windows GUI with C#,
but I am not responsible for that.

Do you know if it is possible to throw native C++ exceptions from the C++
layer, and directly catch them at the C++/CLI or C# layer?

Or must the C++/CLI layer catch all native C++ exceptions (like those
derived from std::exception) and rethrow them in a different form, derived
from managed base exception class System.Exception ?

Thanks,
Giovanni
 
Giovanni said:
Do you know if it is possible to throw native C++ exceptions from the C++
layer, and directly catch them at the C++/CLI or C# layer?

Or must the C++/CLI layer catch all native C++ exceptions (like those
derived from std::exception) and rethrow them in a different form, derived
from managed base exception class System.Exception ?

Giovanni:

I don't know about that. The code I am talking about is a mathematical library
that uses exceptions (derived from std::exception) internally, but catches them
and converts them to error codes for the client.
 
There are several type of code where C++ is either better or
plain necessary.

But is "write MSI custom actions for installers" really a common task ?

If you develop desktop applications, you typically have to make
installers for them. And, yes, given the limitations of Windows
Installer, it often requires one to write a custom action to do a
particular check or operation.
 
Giovanni:

I don't know about that. The code I am talking about is a mathematical
library that uses exceptions (derived from std::exception) internally, but
catches them and converts them to error codes for the client.

Thanks David.

Giovanni
 
I would have to disagree.

There is a lot of C++ code about that is lower-level than it needs to
be. When sensibly used C++ can result in code that is every bit as
high-level an abstraction of the business logic as you get with C#.

I agree with Daniel.

The main problem of C++ code is "old style" C++ code, more similar to C than
C++.
e.g. when raw pointers like char* are used instead of robust string classes
like std::string/CString, or instead of robust container classes like
std::vector.

Using tools like string classes, container classes and smart pointers makes
C++ code robust and easy to write and manage.

Giovanni
 
[Daniel James]
It's perfectly possibly to use C++/CLI to write GUI .NET applications --
it wouldn't be everybody's choice (for a number of good reasons) but it
is certainly possible ... and what Microsoft "recommend" shouldn't play
a big part in your decision-making process. Their recommendations are
often more political than technical, and in any case can't consider the
specific technical factors affecting any individual case.

For that matter: I don't think I've seen any definitive statement from
Microsoft saying that C++/CLI is no longer recommended for GUI .NET
applications ... can you provide a reference/link for that?

I would suggest reading this comment by Steve Teixeira to Somasegar's blog
post titled "Visual C++ Futures":

http://blogs.msdn.com/somasegar/archive/2007/08/08/visual-c-futures.aspx#4746812

<quote>

[...]

Hopefully I'm helping to paint a more accurate picture of the role of
C++/CLI. In a nutshell, we're focused on areas where we can add maximal
value, and we're deliberately avoiding investments in "me too" areas where
we can offer little value beyond a "C# with a preprocessor" experience. In
practical terms, this will often mean leaving the UI designer space in the
capable hands of C# and VB.NET while VC++ focuses on ensuring developers can
get the most out of the "guts" of their software.
[...]

Steve Teixeira

Group Program Manager, VC++

</quote>


Giovanni
 
Pavel said:
If you develop desktop applications, you typically have to make
installers for them. And, yes, given the limitations of Windows
Installer, it often requires one to write a custom action to do a
particular check or operation.

Pavel:

Well, I use Inno Setup for my installations, and for that you have to do the
customization in Pascal (unfortunately).
 
Daniel said:
If you are an experienced C++ programmer but know no C# (or other .NET
language) and you want to write an application for the .NET runtime that
has some GUI functionality but a lot more back-end logic it might well
be ideal to use C++/CLI for the whole thing. There are no hard-and-fast
rules, here, just a lot of technologies that can play together or on
their own and which have different strengths and weaknesses.

It's perfectly possibly to use C++/CLI to write GUI .NET applications --
it wouldn't be everybody's choice (for a number of good reasons) but it
is certainly possible ... and what Microsoft "recommend" shouldn't play
a big part in your decision-making process. Their recommendations are
often more political than technical, and in any case can't consider the
specific technical factors affecting any individual case.

For that matter: I don't think I've seen any definitive statement from
Microsoft saying that C++/CLI is no longer recommended for GUI .NET
applications ... can you provide a reference/link for that?


That's certainly a valid choice, and a reasonable one for a native C++
application that's limited to the Windows platform.

Other good choices would be Qt or the wxWdigets libraries which also
target other OSes, such as linux and MacOS.


Yes, indeed. It's also an appropriate strategy if you want your back-end
code to be portable to ther systems but want to code a platform-specific
GUI for each target system to take best advantage of the facilities of
each platform. The Windows front-end can then be C# (or whatever takes
your fancy), and you can use other tools for other platforms.

Daniel:

These are indeed difficult decisions, and I do not believe the dust has fully
settled on the managed/native issue (maybe it never will).

I for one am glad that I have stuck with native code and MFC up till now.
Investing a lot of time in MC++ would certainly have been a big mistake, and
it's beginning to look like the same for C++/CLI (at least for GUI).

QT or wxwidgets are good for cross-platform, but QT is expensive and I'm not
sure about the longevity of wxwidgets. But really I do not think about porting
my applications any more, because I feel that CrossOver MAC and CrossOver Linux
do a pretty good job of running Windows applications.

So although I started out separating the "business logic" of my application from
the GUI (and writing the former in just ANSI C++, with no Microsoft-specific
stuff), I now think of using it in a revised app with the GUI in .NET and C#.
But not any time soon.

It's a pity that Microsoft's only supported native C++ GUI platform is MFC, but
there it is. It's inelegant, and bloated, but it works, for the most part. So
for now I'm sticking with MFC, forgetting about C++/CLI, and starting to learn
C# in my spare time.
 
It's a pity that Microsoft's only supported native C++ GUI platform is MFC, but
there it is.

Why restrict yourself to Microsoft-produced GUI frameworks, though? Qt
is an excellent-quality powerful framework with full commercial
support on Windows and Microsoft C++ compilers, and complete Visual
Studio integration - and that's just one example.
 
The main problem of C++ code is "old style" C++ code, more similar to C than
C++.
e.g. when raw pointers like char* are used instead of robust string classes
like std::string/CString, or instead of robust container classes like
std::vector.

Using tools like string classes, container classes and smart pointers makes
C++ code robust and easy to write and manage.

Well, sort of. Until you accidentially invalidate an iterator by
modifying the container - U.B. Or mix signed and unsigned integer
types in an arithmetic expression and get weird results because of the
silent signed->unsigned conversion rule (and it is very easy to do so,
since a lot of standard library functions return unsigned integers -
e.g. size() of any STL container is unsigned). Or forget that
assignment operator and "copy" constructor for auto_ptr are actually
move and not copy. Or put an auto_ptr into a container (and why not,
if it lets you do so without any compaints...). Or try to make sense
of three paragraphs of ISO C++ standard describing overload resolution
for template functions in presence of partial specializations (the one
where synthetic types are involved). The problem is, you have to be a C
++ expert to write good C++ code, and, not any less important, to be
able to understand advanced C++ code written by others that's thrown
at you.

Don't get me wrong, C++ is a great language, and the time I've spent
writing in it was great. But from my experience, I would never let it
anywhere near domain logic except where it is spefically needed, when
I have the choice, because too many times I've witnessed how even
skilled and experienced (5+ years) C++ developers wrote some seemingy
trivial code which then broke things in subtle ways. I once spent 2
whole work days in the debugger trying to find the code that lead to
"Heap corrupted" error which invariably manifested itself under
unclear conditions after the program was used for 2-3 hours. It's not
fun at all. It's also something that's much, much rarer in the
"managed code" land.
 
David said:
So although I started out separating the "business logic" of my
application from the GUI (and writing the former in just ANSI C++, with
no Microsoft-specific stuff), I now think of using it in a revised app
with the GUI in .NET and C#. But not any time soon.

Oops. I meant to say that while my original reason for separating GUI from
business logic was for porting to Mac or Linux, I now think it more likely that
I will use my native C++ business logic in a .NET C# application on Windows.
 
I have the choice, because too many times I've witnessed how even
skilled and experienced (5+ years) C++ developers wrote some seemingy
trivial code which then broke things in subtle ways. I once spent 2
whole work days in the debugger trying to find the code that lead to
"Heap corrupted" error which invariably manifested itself under
unclear conditions after the program was used for 2-3 hours. It's not
fun at all. It's also something that's much, much rarer in the
"managed code" land.

I completely agree with you. After many years in the field I have yet to
meet one C++ programmer whose code I actually trust. Experience typically
makes little difference. Novices will make many mistakes because they're
inexperienced. The experienced will still make many mistakes but at this
stage they should know better. Design skills are another matter entirely
(usually very poor). This is not arrogance speaking because I know there are
decent programmers out there. Unfortunately they are few and far between.
Most are just a very expensive burden on their employers and management is
usually clueless. I once met a very senior person in C++ circles (I won't
mention his name) and I asked him for his opinion. He suggested that perhaps
5% of all C++ programmers are competent. I wish I were that optimistic.
 
Daniel said:
I would have to disagree.

There is a lot of C++ code about that is lower-level than it needs to
be. When sensibly used C++ can result in code that is every bit as
high-level an abstraction of the business logic as you get with C#.

Sure, bad C++ programming will lead to a poor abstraction and
overcomplex code, but so will bad programming in any language.

But it is easier to write bad code in C++ than in so many'
other languages.

C++ has some very unsafe constructs (many of them inherited from C).
The C++ language is pretty complex to master. C++ has all the
implementation specific/undefined gotchas. And there is usually a
gap between the C++ standard and the C++ compilers implementation.

Arne
 
Daniel said:
Thanks for that. I had seen it before ... and I don't see anything there
that suggests that C++/CLI is "not recommended" for GUI code. All Steve
says that's at all relevant is that MS don't propose to spend time writing
GUI design tools that target C++/CLI when they already have some that
target C# and there are other things they want to spend resources on to
support C++.

That's a fair enough viewpoint, and the message in the blog is that MS (or,
at least, the C++ team) are following what they believe to be the wishes of
their customers in that respect.

That doesn't mean that they don't recommend using C++/CLI, it means that
they won't provide any tools to help you do that. That's not big deal,
really, because it doesn't actually matter what language any automatically
generated code is in -- the form designer might as well spit out a compiled
assembly as C#. Microsoft do say that the C# generated by the designers
isn't supposed to be edited by the user -- that's how they get away with
emitting such poorly structured code.

You don't actually *need* to have any tools to help you write GUI code,
anyway. You can do it all by hand. The form designers may save you some
time but in a large project that time is not significant, and hand-crafted
code will be better structured and more maintainable than anything that
comes from the designers.

Daniel:

Maybe I should not say "Microsoft does not recommend" then. Do you think
"Microsoft does not promote" would be more accurate? Or do you feel that is too
strong also?

I'm sure there are some advanced users who use C++/CLI to write GUI .NET
applications, but the vast majority of the C++/CLI questions I see in the
newsgroups/forums come from novices who have downloaded VC++ Express and have
found that, absent MFC, the only out-of-the-box way to write GUI applications is
to use .NET. Many of these folks, like the OP, are not even aware that the
language they are using is not C++. They have chosen C++ because the name sounds
familiar, or perhaps know it a bit already, but the vast majority of these
people would have been batter off downloading VC# Express instead. At any rate,
they are not going to be happy if the forms designer in VC++ is crippled.

But even experienced C++ users seem to be embracing C# over C++/CLI. It's not
just the designer tools; some features (such as LINQ) are not even available in
C++/CLI. It's a shame after all the effort that went into C++/CLI (after the
initial MC++ debacle), but there it is.

What's the solution? I think MS has to fully face up to the fact that VC++ is
for native code, get the IDE back to the level of usability/responsiveness we
had in VC6, and put MFC (and the PSDK) into VC++ Express. I don't think it is
anybody's interest to "entrap" beginners into C++/CLI.
 
Pavel Minaev said:
On Jul 19, 4:36 pm, "Giovanni Dicanio" <gdicanio@_NOSPAM_email_DOT_it>
wrote:
[...]
Using tools like string classes, container classes and smart pointers makes
C++ code robust and easy to write and manage.

Well, sort of. Until you accidentially invalidate an iterator by
modifying the container - U.B. Or mix signed and unsigned integer
types in an arithmetic expression and get weird results because of the
silent signed->unsigned conversion rule (and it is very easy to do so,
since a lot of standard library functions return unsigned integers -
e.g. size() of any STL container is unsigned). Or forget that
assignment operator and "copy" constructor for auto_ptr are actually
move and not copy. Or put an auto_ptr into a container (and why not,
if it lets you do so without any compaints...). Or try to make sense
of three paragraphs of ISO C++ standard describing overload resolution
for template functions in presence of partial specializations (the one
where synthetic types are involved). The problem is, you have to be a C
++ expert to write good C++ code, and, not any less important, to be
able to understand advanced C++ code written by others that's thrown
at you.

I've looked at this list and I agree with the unsigned vs. signed
issue, everything else I don't agree with. I can't see how you can
implement a dynamic array that doesn't invalidate iterators upon
insertion (might be my limited imagination, though).
I don't think I've used 'std::auto_ptr' in the last five years. If
I needed a smart pointer (which is rather rare if you use the above
mentioned tools) I needed (and used) a ref-counting off-the-shelf
one. And there's no function template partial specialization, so it
can't mess with the overloading rules.
I agree that C++ is a huge and complex beast to deal with, but I
also agree with Giovanni that a modern use of it leads to save,
robust, and easily maintainable code. Unfortunately I also have to
agree that too few programmers are using it that way.

I think it all boils down to the old observation that C's heritage
is both a bless and a curse for C++. That's valid for teaching it,
too. C++ was taught as a better C for far too long and that still
hasn't changed enough. To many studentsare taught a style that begs
for subtle bugs, alltough there are better ways to make use of the
language.
My personal opinion is that most programmers would benefit a lot
from reading Koenig/Moo's "Accelerated C++" even though it's meant to
be for novices. I read it many years ago (because I teach C++) and
while I don't think it showed me anything I didn't know yet, it did
teach me that C++ has changed enough throughout the last 15 years to
make it possible to teach it to students in a way that makes them
programming the style Giovanni advertized from day one.
I have 15-20 lectures (90mins each) to teach C++ to students who had
one year of Java-only exposure and found that it's possible to go all
the way from "Hello, world!" to template meta-programming in that
time. I hammer a lot of rules of thumb into them and teach them a
style where C++ is a like big box of Lego bricks from which your can
safely build anything you need. I rarely ever have a semester where I
give an exercise where they have to write 'new', let alone 'delete',
but they see 'std::vector' in lesson two, along with 'std::string'
and IO. C++ is still more unsafe than other languages because it just
relies on programmers not to do stupid things, but given a modern
combination of compiler/RTL/std lib you get a lot of meaningful run-
time error messages in debug mode while still enjoying full speed in
release mode.
Don't get me wrong, C++ is a great language, and the time I've spent
writing in it was great. But from my experience, I would never let it
anywhere near domain logic except where it is spefically needed, when
I have the choice, because too many times I've witnessed how even
skilled and experienced (5+ years) C++ developers wrote some seemingy
trivial code which then broke things in subtle ways.

But that's really hard to do if you don't do manual memory and the
like. Mostly this happens because programmers only use C++ as a
better C -- which is exactly what Giovanni said would lead to subtle
bugs.
I once spent 2
whole work days in the debugger trying to find the code that lead to
"Heap corrupted" error which invariably manifested itself under
unclear conditions after the program was used for 2-3 hours. It's not
fun at all. It's also something that's much, much rarer in the
"managed code" land.

IME the crashs reported from testing tend to happen in certain parts
of the code and correlate with the style used in there. I rarely saw
more than one crash per year in my code /while testing on my machine/
and went years without having one checked in.
And that's not really hard to do if you write code the way Giovanni
suggests.

Schobi
 
  I've looked at this list and I agree with the unsigned vs. signed
  issue, everything else I don't agree with. I can't see how you can
  implement a dynamic array that doesn't invalidate iterators upon
  insertion (might be my limited imagination, though).

Depends on the container, but that was not my point. In C#, if you use
an invalid enumerator, you will _consistently_ get an exception. In C+
+, unless you're using a debugging STL implementation (and even then
all checks are usually disabled in release mode by default), your
invalidate vector iterator will happily dereference, and you'll get a
segfault at best, and will silently read or write some random memory
value at worst - it's precisely how those "heap corruption" errors
appear.
  I don't think I've used 'std::auto_ptr' in the last five years. If
  I needed a smart pointer (which is rather rare if you use the above
  mentioned tools) I needed (and used) a ref-counting off-the-shelf
  one.

Ironically, a typical C++ refcounted smart pointer is often on average
slower than a good mark&sweep GC. Especially if you're using Boost/TR1
shared_ptr, which allocates the reference counter separately from the
object itself.
And there's no function template partial specialization, so it
 can't mess with the overloading rules.

My mistake, sorry. Just plain template specializations, not partial
ones.

By the way, partial function specialization will be in C++0x, so those
3 paragraphs might well become a few more :)
  I agree that C++ is a huge and complex beast to deal with, but I
  also agree with Giovanni that a modern use of it leads to save,
  robust, and easily maintainable code. Unfortunately I also have to
  agree that too few programmers are using it that way.

There's one more thing to it. "Modern use" of C++ really looks a lot
like C# or Java - you generally see MI only in context of abstract
base classes (read: interfaces), you see proliferation of pointers
over stack-allocated objects (again, because of interfaces), you don't
see many overly clever template metaprogramming abuses etc.

The question is then, if the "modern subset" of C++ closely matches
that of C#, but C# also doesn't have all the legacy cruft, then why
choose C++ over C# for a typical project?

(There are other valid reasons such as portability, but I'm
deliberately restricting this argument to languages only, not to
available implementations).
  and IO. C++ is still more unsafe than other languages because it just
  relies on programmers not to do stupid things, but given a modern
  combination of compiler/RTL/std lib you get a lot of meaningful run-
  time error messages in debug mode while still enjoying full speed in
  release mode.

Until we get concepts in C++0x, essentially any C++ program that
heavily uses templates in general, and template metaprogramming in
particular (yes, that includes STL and Boost) is a rather masochistic
exercise when it comes to deciphering compiler error messages.
  But that's really hard to do if you don't do manual memory and the
  like.

Not really. Perhaps I would have to clarify - my observations were in
a development environment where knowledge of the subtleties of C++ was
encouraged and widespread, and usage of STL in its entirety - not just
strings and containers, but also algorithms, binders etc, where
possible - was mandatory; and we also used shared_ptr/weak_ptr from
Boost, as well as a couple of our own Boost-style templates. We
certainly didn't use C++ as "better C" - far from it.
 
What's the solution? I think MS has to fully face up to the fact that VC++
is for native code, get the IDE back to the level of
usability/responsiveness we had in VC6,

100% agree!

and put MFC (and the PSDK) into VC++ Express.

VC++ Express 2008 includes PSDK out-of-the-box.
Unfortunately, MFC is not there.

So, maybe the VC2008 Express users may use WTL for GUI development (I recall
there was an article on CodeProject about that).

However, a beginner who wants to write a GUI app for Windows can save lots
of time if he uses VC# Express with its RAD-style GUI designer.

Giovanni
 
I once met a very senior person in C++ circles (I won't mention his
5%? Maybe. It's certainly no more than about 10%.

The percentage doesn't change much for other languages, though, bad
programmers will write bad code in any language.

That's certainly true, but comparing a typical language to C++ is like
comparing a truck full of eggs to a tanker full of nitroglycerin. If your
driver's incompetent 95% of the time then you'll either end up with a lot of
broken eggs or a lot of dead bodies.
 
Daniel said:
5%? Maybe. It's certainly no more than about 10%.

The percentage doesn't change much for other languages, though, bad
programmers will write bad code in any language.

But in languages like C and C++ they can create bugs that are
both disastrous and very hard to find.

Arne
 
Jon said:
Java 1.4 and C# 1.0 were very similar, but the languages have diverged
significantly since then. Almost all the new features in C# 2.0 and 3.0
either have no real equivalent in Java (e.g. iterator blocks, nullable
types) or have very significant differences (e.g. generics).

I don't agree for 2.0.

My list of .NET 2.0 & C# 2.0 new features and their "Java status":

FtpWebRequest - URLConnection has had support for FTP many years
Ping - missing
HttpListener - missing
GZipStream - GZIP*Stream has existed many years
partial classes - missing
DbProviderFactory - JDBC worked that way always
generics - Java got it in 1.5 (and it is not that different)
nullable types - Java has had wrapper objects forever
anonymous methods - Java has anonymous classes
static classes - missing
different accessability get & set - Java getters & setters obviously can

7 out of 11 seems to be in Java .

..NET 3.0/3.5 & C# 3.0 I will agree. Java does not have much of that
stuff and it does not seem as if Java will get it either in the future.

Arne
 
Back
Top