469,270 Members | 1,164 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,270 developers. It's quick & easy.

learn C++ or C#

If I haven't made substantial investment in either C++ or C#, which language
would the experts recommend I become well acquainted with?

Daniel
Jul 17 '08
151 3783
But hey, if you guys want to keep wasting time arguing about pointless
differences, be my guest.
http://en.wikipedia.org/wiki/Hypocrisy
Jul 24 '08 #101
Peter Duniho wrote:
This distinction has nothing to do with the _language_. If the OS was
entirely garbage collected, then these "non-memory resources" wouldn't
be an issue. They would be managed the same way memory is in .NET and
you'd never have to worry about disposing them.

Now, with certain types of objects you'd still have to deal with
closing, flushing, etc. But that's not something that RAII inherently
solves; it just happens that C++ classes can take advantage of that to
handle those operations. The OS API itself isn't based on C++ and
requires the program to deal with managing those operations.

In C++, RAII provides a convenient way to deal with that, and in C#, the
"using" statement does the same. You may prefer one syntax over the
other, but I personally don't see a difference between the two that
would justify an argument of superiority one way or the other. Larry's
claim of "vastly superior" seems particularly baseless. Vastly? Pure
hyperbole.
Not only is the "using" mechanism less convenient/elegant for the client of the
class than RAII (not to mention the possibility of forgetting to do it), but a
C# Dispose'd object can still be used (unlike a C++ object that goes out of
scope or is delete'd). This places an additional burden on the writer of an
IDisposable class.

IMHO, any use of a Dispose'd object should automatically cause a
"ObjectIsDeadException" rather than relying on the author to test and throw an
ObjectDisposedException in every method.

--
David Wilkinson
Visual C++ MVP
Jul 24 '08 #102
On Thu, 24 Jul 2008 11:23:49 -0700, David Wilkinson
<no******@effisols.comwrote:
Not only is the "using" mechanism less convenient/elegant for the client
of the class than RAII (not to mention the possibility of forgetting to
do it), but a C# Dispose'd object can still be used (unlike a C++ object
that goes out of scope or is delete'd).
I was comprehending your post until "or is delete'd". There's nothing in
C++ to stop someone from trying to use an object that's been deleted, and
depending on how the memory was allocated and what the class does in its
destructor, doing so might even work for awhile.
This places an additional burden on the writer of an IDisposable class.
I don't see how it's any more burden than already exists in C++. There's
no requirement that a disposable class actually catch post-disposal uses.
It's nicer, but then so too would it be nicer for a C++ class to catch
uses that occur after destruction. And I think it's easier for a C# class
to do so, because the object is still actually allocated and the code in
the class can behave predictably; in C++, sometimes using an object after
destruction will fail immediately, and sometimes it won't.
IMHO, any use of a Dispose'd object should automatically cause a
"ObjectIsDeadException" rather than relying on the author to test and
throw an ObjectDisposedException in every method.
I don't disagree that RAII allows for an object to simply "disappear" when
the scope is exited, but this is how "using" works in C# too. Variables
declared in the "using" statement are valid only for the scope of the
block of that statement.

And just as in C#, the reference to the variable declared in the "using"
statement could "escape" by being passed to something else, so too could a
pointer to a stack-allocated C++ object escape. RAII in C++ doesn't
actually guarantee that you can't use the object reference after the
object itself has been destroyed. It just ensures that the object is
destroyed outside a particular scope, just as "using" does.

If anything, at least with a garbage collecting system, you know that if
you have a reference to something, that's a valid reference. The object
itself might be in an unusable state, but it will always be able to tell
you that one way or the other.

Again, in terms of any practical difference between the two, any
difference is negligible and not a point worth worrying about in terms of
comparing the languages. One might save a little typing over the other
(and there are other examples going the other direction), but in the
greater scheme of things, that's just not important.

Pete
Jul 24 '08 #103
Larry Smith wrote:
>>>Multi-threading, GUI development is much easier in most of the other
languages compared to the efforts you have to take in C++, because they
support it out of the box. Fortunately C++ has Boost.
To be fair, this has nothing to do with C++ as a language (which has no
support for multi-threading or GUI whatsoever). You have to separate the
tools from the language itself.
I don't think so. What would C++ be without the standard library ?

It would be another language since it must include the library by
definition. Contrast this to C# whose basic support is primitive (see the
standard for yourself). In any case, the claim that GUI development is
"easier" in C# compared to C++ has nothing to do with the languages
The RAD tools have to parse the source code, which is more complex in
C++ and therefore there aren't that much (good) RAD tools for C++ or
they feel somewhat sluggish.
So let's restrict the "easier" part on development of good RAD tools not
on using them.
themselves. It's the rich set of classes in MSFT's framework combined with
better development tools that make C# easier (noting that C# is a natural
fit for the framework unlike C++). Provide an equivalent C++ library and
better tools and it will be just as easy (not taking into account the actual
language differences).
With easier I meant the whole development experience - so it was perhaps
somewhat misleading to use the word "easier".
With development experience I mean Intellisense / refactoring / fast
compilation and so on.

There are GUI frameworks supported by different languages including C++:

C++ (/CLI): WinForms, VCL
C# : WinForms
Delphi : VCL

But IMHO the development experience in C#, Delphi is better than in C++,
just because of the compilation speed. It makes a huge difference if you
wait multiple minutes after having touched the GUI or just a few seconds.

Andre

Jul 24 '08 #104
Peter Duniho wrote:
On Thu, 24 Jul 2008 11:23:49 -0700, David Wilkinson
<no******@effisols.comwrote:
[...]
I don't disagree that RAII allows for an object to simply "disappear"
when the scope is exited, but this is how "using" works in C# too.
Variables declared in the "using" statement are valid only for the scope
of the block of that statement.
[...]
For scoped resource handling I think "using" is a good alternative for
RAII. But I miss RAII sometimes in C#:

E.g:

list (a) - holds a file object (f)
list (b) - holds the same file object (f)

When I remove (f) from list (a) I have to check if list (b) holds the
file object too or rely on GC to close it - but I think that wouldn't be
a good idea, since the file would be open, till the GC has disposed the
object.

In C++ I can use RAII smart pointers to ensure that the file is closed
as soon as it's not used anymore. In C# I have no automatism to handle
this.

I see that there are benefits in GC over RC = reference counting, but
IMHO both are relevant:

GC - for memory
RC - for resources
Andre
Jul 24 '08 #105
Peter Duniho wrote:
>Not only is the "using" mechanism less convenient/elegant for the
client of the class than RAII (not to mention the possibility of
forgetting to do it), but a C# Dispose'd object can still be used
(unlike a C++ object that goes out of scope or is delete'd).

I was comprehending your post until "or is delete'd". There's nothing
in C++ to stop someone from trying to use an object that's been deleted,
and depending on how the memory was allocated and what the class does in
its destructor, doing so might even work for awhile.
>This places an additional burden on the writer of an IDisposable class.

I don't see how it's any more burden than already exists in C++.
There's no requirement that a disposable class actually catch
post-disposal uses. It's nicer, but then so too would it be nicer for a
C++ class to catch uses that occur after destruction. And I think it's
easier for a C# class to do so, because the object is still actually
allocated and the code in the class can behave predictably; in C++,
sometimes using an object after destruction will fail immediately, and
sometimes it won't.
>IMHO, any use of a Dispose'd object should automatically cause a
"ObjectIsDeadException" rather than relying on the author to test and
throw an ObjectDisposedException in every method.

I don't disagree that RAII allows for an object to simply "disappear"
when the scope is exited, but this is how "using" works in C# too.
Variables declared in the "using" statement are valid only for the scope
of the block of that statement.

And just as in C#, the reference to the variable declared in the "using"
statement could "escape" by being passed to something else, so too could
a pointer to a stack-allocated C++ object escape. RAII in C++ doesn't
actually guarantee that you can't use the object reference after the
object itself has been destroyed. It just ensures that the object is
destroyed outside a particular scope, just as "using" does.

If anything, at least with a garbage collecting system, you know that if
you have a reference to something, that's a valid reference. The object
itself might be in an unusable state, but it will always be able to tell
you that one way or the other.
<snip>

Pete:

Well, I think C++ programmers (even bad ones) are generally aware of lifetime
issues, whereas C# programmers can be lulled into a sense of false security by
the "garbage collector will take care of everything" mindset.

I just find this notion of the "half dead" object rather disturbing. Surely it
would have been possible for the C# language to be defined such that use of a
Dispose'd object automatically throws an exception?

--
David Wilkinson
Visual C++ MVP
Jul 24 '08 #106
On Thu, 24 Jul 2008 12:30:34 -0700, Andre Kaufmann
<an*********************@t-online.dewrote:
[...]
When I remove (f) from list (a) I have to check if list (b) holds the
file object too or rely on GC to close it - but I think that wouldn't be
a good idea, since the file would be open, till the GC has disposed the
object.

In C++ I can use RAII smart pointers to ensure that the file is closed
as soon as it's not used anymore. In C# I have no automatism to handle
this.
But you can include reference counting in the C# object if you want. You
can even implement a "smart pointer" class that uses Dispose() to
decrement the counter and call Dispose() on the wrapped object if it
reaches 0.

Personally, I've had enough headaches with reference counting in my
lifetime, and I try to avoid it when I can, smart pointers
notwithstanding. I prefer to not create designs in the first place where
unique ownership of the object is unclear. But there's nothing about C#
that precludes using that technique if you find yourself in a situation
where you think it's useful or needed.

Pete
Jul 24 '08 #107
On Thu, 24 Jul 2008 12:41:17 -0700, David Wilkinson
<no******@effisols.comwrote:
Well, I think C++ programmers (even bad ones) are generally aware of
lifetime issues, whereas C# programmers can be lulled into a sense of
false security by the "garbage collector will take care of everything"
mindset.
I have seen too much bad C++ code (especially code with rampant memory
leaks) in my life to have the high opinion of bad C++ programmers you
apparently have. Conversely, part of being proficient with C# is
understanding how the garbage collection works, and how that interacts
with the non-garbage-collecting parts of the platform. Only bad C#
programmers are "lulled into a sense of false security".
I just find this notion of the "half dead" object rather disturbing.
Surely it would have been possible for the C# language to be defined
such that use of a Dispose'd object automatically throws an exception?
Well, first of all, to some extent it's a question of what the CLR
requires, not what C# requires. And sure, it could. But why?
IDisposable has a specific goal in mind, and no part of that goal involves
requiring that an object become unusable after Dispose() is called.

Inasmuch as there may be classes out there for which it makes sense to
still be able to use the object after it's been disposed, why should the
language or run-time impose an arbitrary restriction on that ability?

As an example: the Form class does not dispose instances when the Form is
closed if it was shown using ShowDialog(), even though it does if the Form
was shown using Show(). This inconsistent behavior is to allow retrieval
of values from the controls in the form after it's been closed. But one
can easily imagine an implementation that completely separates the
unmanaged aspects from the managed aspects, copying any data from the
unmanaged resources upon disposal so that they are still accessible. Then
closing the modal form could be the same as closing the non-modal form: in
both cases, closing implies disposal.

But one could only make that more consistent behavior as long as the
run-time allows a disposed object to be used after Dispose() is called.

Just because an object is done with its unmanaged resources, that doesn't
mean to me that it's "half-dead". It's just done with the unmanaged
resources. If a class wants to allow disposal prior to actually being
done with the object and still permit certain operations on the object
after disposal, that should be its right.

Pete
Jul 24 '08 #108
Peter Duniho <Np*********@nnowslpianmk.comwrote:

<snip>
Just because an object is done with its unmanaged resources, that doesn't
mean to me that it's "half-dead". It's just done with the unmanaged
resources. If a class wants to allow disposal prior to actually being
done with the object and still permit certain operations on the object
after disposal, that should be its right.
MemoryStream is one example, by the way - you can still call ToArray on
it after closing it as a stream.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Jul 24 '08 #109
A simple example:
>
How do I ensure in C++ that I have successfully overridden a base
class virtual function and that the compiler throws an error if the
base class implementation has changed ?
You can't do that in any language I'm aware of, so it's a non-issue. Did
you mean "error if the signature of the function in the base class has
changed"?
>
Andre

Jul 24 '08 #110
Peter Duniho wrote:
On Thu, 24 Jul 2008 10:25:47 -0700, Giovanni Dicanio
<gdicanio@_nospam_email_dot_itwrote:
>"Peter Duniho"
>>In C++, RAII provides a convenient way to deal with that, and in
C#, the "using" statement does the same. You may prefer one syntax
over the other, but I personally don't see a difference between the
two that would
justify an argument of superiority one way or the other.

Destructor and "scope" syntax in C++ is cleaner, simpler and more
elegant than C# bloated 'using'.

Purely subjective. That sort of claim has no place in a technical
discussion.
It's quite objective. In C++, the burden is on the library developer, the
user needs no extra syntax to benefit from automatic cleanup.
>
>Moreover, there is big difference between C++ RAII and C# "using".

In Andre's words:

<quote>
Using is fine if I hold a resource in a control block, but if the
resource is held by let's say multiple lists, I have to use some
kind of smart pointers to handle the resources efficiently.
</quote>

RAII doesn't _inherently_ support "smart pointers", nor does a garbage
collecting system prevent one from implementing "smart pointers".

As I pointed out before, in a 100% GC-ed system, "smart pointers"
become unnecessary anyway. But in a mixed system (i.e. pretty much
Nothing could be further from the truth. Lazy (or deferred, if you prefer)
cleanup breaks access to shared resources, and does so
non-deterministically.
any current platform), it's entirely possible to implement "smart
pointers", and they can work in a very similar way to that
implemented with RAII.
No, in C# it's not possible to create an object that automatically performs
cleanup when it becomes unreachable. You can only do so (1) manually, or
(2) when its memory is reclaimed.
>
Which only brings us back to your purely subjective complaints about
"using".

Pete

Jul 24 '08 #111
Peter Duniho wrote:
On Thu, 24 Jul 2008 10:35:59 -0700, Larry Smith <no_spam@_nospam.com>
wrote:
>>In C++, RAII provides a convenient way to deal with that, and in
C#, the "using" statement does the same. You may prefer one syntax
over the other, but I personally don't see a difference between the
two that would
justify an argument of superiority one way or the other

That's hardly a valid argument, considering that RAII requires no
"using" statement whatsoever. This alone justifies an argument that
there is a difference in favour of C++ (in contrast to your
assertion).

You save a whole line of code. Wow! Yup...that definitely outweighs
any advantage that garbage collection has with respect to simplifying
and improving the robustness of memory management. After all, that's
what programmers really care about. I'd much rather save a line of
code than make it more likely that my code is correct.
The C# way is brittle. If C# let you use a using statement with types that
don't support IDisposable, then it would be better. But right now, adding
IDisposable support to an existing class is always an impermissible breaking
change.

In C++, you can add a destructor without any changes to the code which
references the class.

That's a much bigger issue than saving a single line of code.
Jul 24 '08 #112
Peter Duniho wrote:
On Thu, 24 Jul 2008 11:23:49 -0700, David Wilkinson
<no******@effisols.comwrote:
>Not only is the "using" mechanism less convenient/elegant for the
client of the class than RAII (not to mention the possibility of
forgetting to do it), but a C# Dispose'd object can still be used
(unlike a C++ object that goes out of scope or is delete'd).

I was comprehending your post until "or is delete'd". There's
nothing in C++ to stop someone from trying to use an object that's
been deleted, and depending on how the memory was allocated and what
the class does in its destructor, doing so might even work for awhile.
C++ delete calls the implementation of 'operator delete' after running the
destructor, which can mark the memory with a pattern (or on some CPUs, even
set up data breakpoints to trap any future access to that memory) which in
debug builds would detect use after free. You can use something like
electric fence which will deallocate the segment, generating a segfault on
any future access to that object. All of which can be done without any
changes to the class being protected.

So no, these aren't "in C++", because one of the prime ideals of C++ is "you
don't pay for what you don't use". You turn on these features during
debugging, and perhaps in extremely critical environments where failure
detection is more important than efficiency you might leave them on in the
release build. In all other circumstances, you convince yourself through
thorough testing that these sorts of bugs have been eliminated, and disable
the checks.
Jul 24 '08 #113
On Thu, 24 Jul 2008 15:14:38 -0700, Ben Voigt [C++ MVP]
<rb*@nospam.nospamwrote:
>>Destructor and "scope" syntax in C++ is cleaner, simpler and more
elegant than C# bloated 'using'.

Purely subjective. That sort of claim has no place in a technical
discussion.

It's quite objective. In C++, the burden is on the library developer,
the
user needs no extra syntax to benefit from automatic cleanup.
You don't seem to have read the statements you quoted.

I'm talking about the question of the syntax itself, not the semantics.
The need to include a "using" statement is not a "burden". It's just a
different way to write the same thing.
[...]
>As I pointed out before, in a 100% GC-ed system, "smart pointers"
become unnecessary anyway. But in a mixed system (i.e. pretty much

Nothing could be further from the truth.
Ah, more hyperbole. Yup...that really makes your point compelling.
Lazy (or deferred, if you prefer)
cleanup breaks access to shared resources, and does so
non-deterministically.
In a 100% GC-ed system, a resource that's eligible for "cleanup" is not
"shared" by any code anywhere, by definition. Your statement makes no
sense.
>any current platform), it's entirely possible to implement "smart
pointers", and they can work in a very similar way to that
implemented with RAII.

No, in C# it's not possible to create an object that automatically
performs
cleanup when it becomes unreachable.
I never said it was. But nice straw man.

Pete
Jul 24 '08 #114
On Thu, 24 Jul 2008 15:17:05 -0700, Ben Voigt [C++ MVP]
<rb*@nospam.nospamwrote:
The C# way is brittle. If C# let you use a using statement with types
that
don't support IDisposable, then it would be better. But right now,
adding
IDisposable support to an existing class is always an impermissible
breaking
change.

In C++, you can add a destructor without any changes to the code which
references the class.
If C++ didn't have its own brittle behaviors (including limitations on the
use of stack-allocated classes), I might think your point has some merit
here.

But it does, so I don't.

Pete
Jul 24 '08 #115
On Thu, 24 Jul 2008 15:22:47 -0700, Ben Voigt [C++ MVP]
<rb*@nospam.nospamwrote:
[...essay on C++ built-in testing aids...]
In all other circumstances, you convince yourself through
thorough testing that these sorts of bugs have been eliminated, and
disable
the checks.
Yes, I'm aware of all of the debugging aids C++ includes so that you can
hopefully detect coding errors that simply aren't possible in C#.

As far as I'm concerned, you're just making my point for me.
Jul 24 '08 #116
Peter Duniho wrote:
On Thu, 24 Jul 2008 12:30:34 -0700, Andre Kaufmann
<an*********************@t-online.dewrote:

[...]
But you can include reference counting in the C# object if you want.
You can even implement a "smart pointer" class that uses Dispose() to
decrement the counter and call Dispose() on the wrapped object if it
reaches 0.
I can include reference counting, but I can't use smart pointers. I
prefer GC memory handling, but for resources GC can't be used
effectively, because often resources have to be released directly.
I do a lot of multi threaded programming, there I permanently have the
need of some kind of reference counted resource handling.

[...]
But there's nothing about C# that precludes using that
technique if you find yourself i
If you could add methods to value structures in C# I would agree. But
currently in C# you have to either use a temporary object in combination
with using or call the AddRef / Release functions by hand.

Perhaps it wouldn't be a good idea to add the complexity of C++ which
allows RAII to C#, but some kind of simple automatism would IMHO help too.

E.g. the temporary objects could be replaced by some kind of using which
calls specified methods of an object.

Pseudo code:

MyObject o; // member variable
....
autocall(o) --calls enter / leave methods automatically
{ // call o.enter()
} // call o.leave()

Pete
Andre
Jul 25 '08 #117
On Thu, 24 Jul 2008 22:43:52 -0700, Andre Kaufmann
<an*********************@t-online.dewrote:
Peter Duniho wrote:
>On Thu, 24 Jul 2008 12:30:34 -0700, Andre Kaufmann
<an*********************@t-online.dewrote:
[...]
But you can include reference counting in the C# object if you want.
You can even implement a "smart pointer" class that uses Dispose() to
decrement the counter and call Dispose() on the wrapped object if it
reaches 0.

I can include reference counting, but I can't use smart pointers.
Why not?
I prefer GC memory handling, but for resources GC can't be used
effectively, because often resources have to be released directly.
I do a lot of multi threaded programming, there I permanently have the
need of some kind of reference counted resource handling.
For what it's worth, I've done a fair amount of multi-threaded programming
in C# without needing ref-counting.

Not that I agree that ref-counting can't be done in C#, but I've found
that in many cases, what's really needed is a different way of looking at
the problem.
>[...]
But there's nothing about C# that precludes using that
technique if you find yourself i

If you could add methods to value structures in C# I would agree.
I don't know what you mean here. What methods do you want to add? To
what structure? How would that help?
But currently in C# you have to either use a temporary object in
combination with using or call the AddRef / Release functions by hand.
How is a smart pointer not a temporary object?
Perhaps it wouldn't be a good idea to add the complexity of C++ which
allows RAII to C#, but some kind of simple automatism would IMHO help
too.

E.g. the temporary objects could be replaced by some kind of using which
calls specified methods of an object.

Pseudo code:

MyObject o; // member variable
....
autocall(o) --calls enter / leave methods automatically
{ // call o.enter()
} // call o.leave()
Why not just create a smart-pointer-like class or struct that does that
with the "using" statement? Adds a ref when the object is created,
decrements the ref on disposal, zero ref-count causes disposal of the
wrapped object.

Maybe I'm just being obtuse, but I don't see what the big problem is.

Pete
Jul 25 '08 #118
In article news:<Od**************@TK2MSFTNGP02.phx.gbl>, Mc wrote:
Yes... the big difference is that with C#, errors manifest themselves
as incorrect output or recognizable error messages rather than random
crashes or memory leaks.
At least you KNOW there's something wrong when you get a random crash ...
that incorrect output you get from your C# program is really much more
dangerous.

I think you and Larry and others here blowing the C# trumpet are vastly
over-stating the case about C++ being hard to use and hard to get right.
The fact is that bad programmers will write bad code in any language, and
if you want good code you have to employ good programmers. Once you have
those your problems will start to go away -- whatever language you are
using.

Of course, you need good management, too. Bad management and irrational
budgetary constraints can ruin a project just as easily as bad programming.

Cheers,
Daniel.
Jul 25 '08 #119
In article news:<OP**************@TK2MSFTNGP04.phx.gbl>, Larry Smith wrote:
I also have some serious pet peeves. Why didn't they permit local
classes to be passed as template arguments. I once asked Stroustrup
about this at a conference but I wasn't satisfied with his terse
response.
I think the answer to that is "it looked too hard at the time" ... and IIRC
that constraint is to be removed an some future version of the standard.

I certainly agree that the ability to use a local class as an argument
would make the use of for_each much more natural.
C# allows me to use anonymous methods which is so
much cleaner
You can achieve the same sort of effect with boost::lambda
Even very experienced developers have to continuously bend their
minds out of shape and remain on guard years after learning the
language. This is not the hallmark of a successful language in
spite of C++'s "stellar" reputation and the millions who
continue struggling with it.
I think it's /only/ the very experienced developers (and those who aren't
but think they are -- which is more worrying) who "continuously bend their
minds out of shape" looking for new ways to use the expressive power of the
language. These are the library builders, the Boost developers, the
Alexandrescus of the world ... most C++ programmers just /use/ their work
and are grateful for the way that it makes their lives easier and more
pleasant.

Cheers,
Daniel.

Jul 25 '08 #120
>Yes... the big difference is that with C#, errors manifest themselves
>as incorrect output or recognizable error messages rather than random
crashes or memory leaks.

At least you KNOW there's something wrong when you get a random crash ...
Assuming it does crash. C++ can not only suffer from the same "incorrect
output" as C# (and to a potentially much greater degree), but it can also
result in very serious (and potentially "random") problems that may not
manifest themselves until long after the problem has occurred (in ways that
C# just isn't susceptible to). And you may never even notice it. You may be
filling your DB with garbage, generating invalid reports, displaying
incorrect information for users, etc., but it may not come to anyone's
attention depending on the nature of the problem. And if (when) it does, it
may be incredibly difficult if not (practically) impossible to track it
down.
that incorrect output you get from your C# program is really much more
dangerous.

I think you and Larry and others here blowing the C# trumpet are vastly
over-stating the case about C++ being hard to use and hard to get right.
The fact is that bad programmers will write bad code in any language, and
if you want good code you have to employ good programmers. Once you have
those your problems will start to go away -- whatever language you are
using.

Of course, you need good management, too. Bad management and irrational
budgetary constraints can ruin a project just as easily as bad
programming.
Lol. You must have just graduated.
Jul 25 '08 #121
>I also have some serious pet peeves. Why didn't they permit local
>classes to be passed as template arguments. I once asked Stroustrup
about this at a conference but I wasn't satisfied with his terse
response.

I think the answer to that is "it looked too hard at the time" ... and
IIRC
that constraint is to be removed an some future version of the standard.
Too hard? Maybe too little time to work out the details at the time but it
had something to do with the binding rules according to Stroustrup. I don't
recall the limited details he provided off-hand.
>Even very experienced developers have to continuously bend their
minds out of shape and remain on guard years after learning the
language. This is not the hallmark of a successful language in
spite of C++'s "stellar" reputation and the millions who
continue struggling with it.

I think it's /only/ the very experienced developers (and those who aren't
but think they are -- which is more worrying) who "continuously bend their
minds out of shape" looking for new ways to use the expressive power of
the
language. These are the library builders, the Boost developers, the
Alexandrescus of the world ... most C++ programmers just /use/ their work
and are grateful for the way that it makes their lives easier and more
pleasant.
Most code in the real world is mediocre at best but usually much worse. It's
usually indicative of people who don't have their heads wrapped around the
language and how to program in general (opposed to pushing the limits of the
language). Even very experienced (skilled) programmers still have to
exercise a lot of caution and deal with complex issues not common in other
languages (not always but frequently enough). Most C++ programmers may be
"grateful" but the majority are causing serious problems for their
companies, their colleagues, and their users. Most of them function in a
state of ignorant bliss and management usually doesn't understand the scope
of the problem.
Jul 25 '08 #122
Peter Duniho wrote:
On Thu, 24 Jul 2008 22:43:52 -0700, Andre Kaufmann
<an*********************@t-online.dewrote:
[...]
>I can include reference counting, but I can't use smart pointers.

Why not?
Not in that way as they are used in C++.

E.g. if I assign one smart pointer to another in C++ the reference is
incremented. In C# I would have to use a method for the assignment.
But I can't prevent one smart pointer accidentally be assigned to
another one in C#.
So I don't see that much value in smart pointers in C#, I then rather
would prefer the AddRef method directly and not using a smart pointer.

>I prefer GC memory handling, but for resources GC can't be used
effectively, because often resources have to be released directly.
I do a lot of multi threaded programming, there I permanently have the
need of some kind of reference counted resource handling.

For what it's worth, I've done a fair amount of multi-threaded
programming in C# without needing ref-counting.
For example in the following architecture:

A simple shared buffer holding memory and resources: [b]

[b] -Thread #1
[b] ---[ReceiverThread] - passes --[b] -Thread #2
[b] -Thread #3

The buffer is passed to multiple receivers which "do something" with the
buffer. After the last thread has finished it's operations it should
release the buffer and store it into a central pool for reusing and
should additionally release eventually used resources immediately.
How do I know if the last thread has finished ?
Not that I agree that ref-counting can't be done in C#, but I've found
that in many cases, what's really needed is a different way of looking
at the problem.
Yes, reference counting can surely be done in C#. But I don't see how I
could use reference counting with smart pointers in C# ---- outside of a
control block.
>>[...]
But there's nothing about C# that precludes using that
technique if you find yourself i

If you could add methods to value structures in C# I would agree.

I don't know what you mean here. What methods do you want to add? To
what structure? How would that help?
A structure is a value type in C# and therefore copied on assignment and
immediately "freed" if the control block is left.
If I could add an destructor and overload the assignment operator I
would have a possibility to implement smart pointers like in C++.

>But currently in C# you have to either use a temporary object in
combination with using or call the AddRef / Release functions by hand.

How is a smart pointer not a temporary object?
Yes, that's the point. I know how to handle it temporarily in a control
block, but when the smart pointer is added to a list of smart pointers
and removed from the list I have no possibility to "force" the automatic
release of the reference.
I have to remove the smart pointer from the list and then manually call
release. What's the point of a smart pointer in this case ? I could
rather use the reference counted object directly
[...]
Why not just create a smart-pointer-like class or struct that does that
with the "using" statement? Adds a ref when the object is created,
decrements the ref on disposal, zero ref-count causes disposal of the
wrapped object.
Maybe I'm just being obtuse, but I don't see what the big problem is.
I only have the feeling that just creating a new object to automatically
call methods of another object in the Dispose method is somewhat
overkill. The GC is fast, but why should I add pressure to it, by
permanently allocating temporary objects ?

I agree It's no big deal if the temporary object is created rarely or
held for a long time.

But additionally a smart pointer should behave like another ordinary
pointer, with additional functionality that is under my control.
Pete
Andre
Jul 25 '08 #123
Ben Voigt [C++ MVP] wrote:
>A simple example:

How do I ensure in C++ that I have successfully overridden a base
class virtual function and that the compiler throws an error if the
base class implementation has changed ?

You can't do that in any language I'm aware of, so it's a non-issue. Did
you mean "error if the signature of the function in the base class has
changed"?
Sorry yes - the signature - function declaration - not the definition or
code inside the function itself.
>
>Andre
Andre
Jul 25 '08 #124
On Fri, 25 Jul 2008 09:35:20 -0700, Andre Kaufmann
<an*********************@t-online.dewrote:
Peter Duniho wrote:
>On Thu, 24 Jul 2008 22:43:52 -0700, Andre Kaufmann
<an*********************@t-online.dewrote:
[...]
>>I can include reference counting, but I can't use smart pointers.
Why not?

Not in that way as they are used in C++.

E.g. if I assign one smart pointer to another in C++ the reference is
incremented. In C# I would have to use a method for the assignment.
But I can't prevent one smart pointer accidentally be assigned to
another one in C#.
So I don't see that much value in smart pointers in C#, I then rather
would prefer the AddRef method directly and not using a smart pointer.
Ah, I see. So it's not that you can't do it. You just don't want to do
it the way you'd need to in C#.

You're right, assignment operator overload isn't available in C#. But
such an overloaded operator's really just another method. There's no
functional difference between simply implementing it as an explicit
method. In fact, some will argue that there's a good reason to not allow
overloading of the assignment operator and that making that sort of thing
explicit is a _good_ "don't blow your leg off" sort of thing. :)
For example in the following architecture:

A simple shared buffer holding memory and resources: [b]

[b] -Thread #1
[b] ---[ReceiverThread] - passes --[b] -Thread #2
[b] -Thread #3

The buffer is passed to multiple receivers which "do something" with the
buffer. After the last thread has finished it's operations it should
release the buffer and store it into a central pool for reusing and
should additionally release eventually used resources immediately.
How do I know if the last thread has finished ?
There are any number of approaches you can take. But if you really like
ref-counting, then the solution is to just ref-count the object. I don't
know what the phrase "eventually used resources" means, but if you're
pooling the object I don't see why you'd release its resources.
Conversely, if you're releasing its resources, then just get rid of the
object and be done with it.

In either case, you may still want _some_ form of ref-counting, either
managed by the pool manager itself, or as part of the object. But either
way, it's much ado about nothing.
[...]
A structure is a value type in C# and therefore copied on assignment and
immediately "freed" if the control block is left.
If I could add an destructor and overload the assignment operator I
would have a possibility to implement smart pointers like in C++.
IDisposable can replace the functionality of the destructor (in
conjunction with the "using" statement), and yes you'd have to have an
explicit method instead of an overloaded assignment operator. I don't
find those differences to be material.
>>But currently in C# you have to either use a temporary object in
combination with using or call the AddRef / Release functions by hand.
How is a smart pointer not a temporary object?

Yes, that's the point. I know how to handle it temporarily in a control
block, but when the smart pointer is added to a list of smart pointers
and removed from the list I have no possibility to "force" the automatic
release of the reference.
I have to remove the smart pointer from the list and then manually call
release. What's the point of a smart pointer in this case ? I could
rather use the reference counted object directly
When the smart pointer is not stack-allocated, don't you have to manually
delete the smart pointer in C++? What's the difference?
[...]
I only have the feeling that just creating a new object to automatically
call methods of another object in the Dispose method is somewhat
overkill.
Well, certainly there is the question of just how important smart pointers
are. Personally, I find them superfluous. You can still get ref-counting
bugs even if you're using smart pointers, if you use them incorrectly.
But inasmuch as there's some benefit to wrapping ref-counting in a
clearer, more automatic API, that benefit is available in C#, just using
slightly different syntax.
The GC is fast, but why should I add pressure to it, by permanently
allocating temporary objects ?
The phrase "permanently allocating temporary objects" doesn't make sense
to me. But regardless, the last thing you really need to worry about is
pressuring the GC. Assuming you're using a reference type for your smart
pointer (which may or may not be true anyway), the GC can handle the load
just fine.
I agree It's no big deal if the temporary object is created rarely or
held for a long time.
Au contraire. One of the GC's strengths is its ability to deal with large
numbers of frequently allocated, short-lived objects.
But additionally a smart pointer should behave like another ordinary
pointer, with additional functionality that is under my control.
To some extent, the real issue here is that there's a fundamental paradigm
shift that needs to be made. If you don't want to make that shift, that's
fine. But that's not an indictment of C#. The whole concept of "smart
pointer" is related to the needs of unmanaged code (and especially COM).
An application written to the strengths of C# and the .NET Framework will
most often never run into ref-counting issues at all, and if and when it
does happen, there are viable work-arounds.

Again: much ado about nothing.

Pete
Jul 25 '08 #125
Peter Duniho wrote:
You save a whole line of code. Wow!
Sorry, you just completely missing the point of RAII...

In C++ I can write a class Thingie that employs RAII for resource
management and then anybody can use it without caring about how it does
it's stuff.

In C# you can write the same Thingie but it's user is required to only
use it in the context of 'using' statement (or it will leak resources).
Jul 25 '08 #126
Peter Duniho wrote:
On Fri, 25 Jul 2008 09:35:20 -0700, Andre Kaufmann
<an*********************@t-online.dewrote:

[...]
You're right, assignment operator overload isn't available in C#. But
such an overloaded operator's really just another method. There's no
functional difference between simply implementing it as an explicit
method. In fact, some will argue that there's a good reason to not
allow overloading of the assignment operator and that making that sort
of thing explicit is a _good_ "don't blow your leg off" sort of thing. :)
May be. But I have to protect the smart pointer somehow, so preventing
an assignment would be sufficient.
[...]
There are any number of approaches you can take. But if you really like
ref-counting, then the solution is to just ref-count the object. I
I don't like it that much, but I don't see a better solution for
efficient resource handling.
don't know what the phrase "eventually used resources" means, but if
you're pooling the object I don't see why you'd release its resources.
Conversely, if you're releasing its resources, then just get rid of the
object and be done with it.
To release the resources I too have to know when the last thread has
finished. A resource could be for example a large memory buffer. IMHO it
wouldn't be wise to frequently allocate - dispose large objects in C#.
[...]
When the smart pointer is not stack-allocated, don't you have to
manually delete the smart pointer in C++? What's the difference?
Smart pointers aren't allocated (normally) on the heap in C++.
Everywhere you are using them, they are either stack allocated or
embedded in an object. It's up to the compiler to generate the
appropriate code to call the destructor.
[...]

The phrase "permanently allocating temporary objects" doesn't make sense
to me. But regardless, the last thing you really need to worry about is
pressuring the GC. Assuming you're using a reference type for your
smart pointer (which may or may not be true anyway), the GC can handle
the load just fine.
Yes, GC is quite fast - under Windows. I think under Mono it's somewhat
different. But anyways I just want to call 2 methods of another object,
it's IMHO just somewhat overkill to create a temporary object just for
that.

IIRC lock(..) in C# simply calls 2 methods. Would be fine if I could use
the same functionality for other objects and methods.

>
To some extent, the real issue here is that there's a fundamental
paradigm shift that needs to be made. If you don't want to make that
I'm fine so far with C# - it has many strengths and I like it. But I
only miss the control C++ offered me - sometimes.
shift, that's fine. But that's not an indictment of C#. The whole
concept of "smart pointer" is related to the needs of unmanaged code
(and especially COM). An application written to the strengths of C# and
the .NET Framework will most often never run into ref-counting issues at
all, and if and when it does happen, there are viable work-arounds.
The D language for example combines both - garbage collection and RAII.
Additionally I can use C++/CLI which also supports RAII for managed
programming.
But the downside is, C++/CLI is damn slow in compilation compared to C#,
because it's a full fledged C++ compiler. And regarding managed
application development it's IMHO only a second class citizen.

So I prefer C# anyways for this task.
Again: much ado about nothing.
Yes, it's not a vital feature. But the discussion was about RAII, which
isn't used for smart pointers only.
It would only be a feature, that would make C# more attractive to C++
developers ;-)
Pete
Andre
Jul 25 '08 #127
On Jul 25, 5:45 am, Daniel James <wastebas...@nospam.aaisp.orgwrote:
In article <news:OP**************@TK2MSFTNGP04.phx.gbl>, Larry Smith wrote:
I also have some serious pet peeves. Why didn't they permit local
classes to be passed as template arguments. I once askedStroustrup
about this at a conference but I wasn't satisfied with his terse
response.

I think the answer to that is "it looked too hard at the time" ... and IIRC
that constraint is to be removed an some future version of the standard.
C++0x will support local types as template arguments. The implementors
who had problems have found a way.
Jul 25 '08 #128
In article news:<OA**************@TK2MSFTNGP04.phx.gbl>, Larry Smith wrote:
Assuming it does crash. C++ can not only suffer from the same
"incorrect output" as C# ... but it can also ..
Certainly -- Point taken -- I didn't mean to suggest that it couldn't.

I was just pointing out that while bad C# code may give you a "nice warm
feeling" by not crashing you should not be lulled into a false sense of
security that it is actually doing the right thing.

C# code needs just as much testing for correctness (and just as much
careful design work to achieve correctness in the first place) as code in
any other language -- it would be wrong to suggest that it did not, or that
doing these things for C# was significantly quicker, cheaper, or easier
than doing them for C++.
Lol. You must have just graduated.
Flattery will get you nowhere -- it took me years to develop this much
cynicism!

Cheers,
Daniel.
Jul 26 '08 #129
C# code needs just as much testing for correctness (and just as much
careful design work to achieve correctness in the first place) as code in
any other language -- it would be wrong to suggest that it did not, or
that
doing these things for C# was significantly quicker, cheaper, or easier
than doing them for C++.
Far from it. While nobody would dispute that program correctness is
demanding in any language, C++ is significantly more demanding to get right
from a purely mechanical perpsective alone. It's also filled with more
trip-wires and gotchas than any other mainstream language. It's easier to
achieve programa correctness when you're strolling down a paved sidewalk
instead of hiking through the jungle.
>Lol. You must have just graduated.

Flattery will get you nowhere -- it took me years to develop this much
cynicism!
It's a strange brand of cynicism you're practicing if you really believe
that "good programmers" and "good management" exist in the real world (in
sufficient numbers to make an appreciable difference). Those who practice
the more conservative brand would simply tell you this is reality. The
panacea you're waiting for may exist somewhere, but it won't save the
majority of us.
Jul 26 '08 #130


"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
On Thu, 24 Jul 2008 15:14:38 -0700, Ben Voigt [C++ MVP]
<rb*@nospam.nospamwrote:
>>>Destructor and "scope" syntax in C++ is cleaner, simpler and more
elegant than C# bloated 'using'.

Purely subjective. That sort of claim has no place in a technical
discussion.

It's quite objective. In C++, the burden is on the library developer,
the
user needs no extra syntax to benefit from automatic cleanup.

You don't seem to have read the statements you quoted.

I'm talking about the question of the syntax itself, not the semantics.
The need to include a "using" statement is not a "burden". It's just a
different way to write the same thing.
Yes, it is a burden. You have to remember the using block at every use of
the class. You have to remember which classes need using blocks and which
don't. And when you add a resource (unmanaged or IDisposable) to a class,
you have to add the IDisposable interface to that class and go back to every
single user and put in the using block.

That's not "a different way to write the same thing" any more than the empty
string is a different way to write a letter.

Or shall I claim that C++'s delete statement and the C# garbage collectors
are just different ways to call the deallocator? Of course they aren't, one
is automatic and the other is not.
>
>[...]
>>As I pointed out before, in a 100% GC-ed system, "smart pointers"
become unnecessary anyway. But in a mixed system (i.e. pretty much

Nothing could be further from the truth.

Ah, more hyperbole. Yup...that really makes your point compelling.
>Lazy (or deferred, if you prefer)
cleanup breaks access to shared resources, and does so
non-deterministically.

In a 100% GC-ed system, a resource that's eligible for "cleanup" is not
"shared" by any code anywhere, by definition. Your statement makes no
sense.
That's why no real-world system is 100% GC-ed. Not .NET, not Java, not any
other. Files, for example, are part of a shared namespace and can't be
garbage collected. And no number of improvements to the garbage collector
are ever going to help with the problem of synchronizing file access. But
all the C# advocates keep pretending that you don't need deterministic
cleanup because you have GC. Yes, you do. A file access object needs to be
cleaned up by releasing a lock on the file, at the point the file access
ceases. Not when you run out of memory (if you run out of memory, if your
program doesn't deadlock waiting for the result of some process which needs
to access that file to continue.
>
>>any current platform), it's entirely possible to implement "smart
pointers", and they can work in a very similar way to that
implemented with RAII.

No, in C# it's not possible to create an object that automatically
performs
cleanup when it becomes unreachable.

I never said it was. But nice straw man.
If it isn't possible in C#, then it obviously isn't just a difference of
syntax as you keep insisting, now is it?
>
Pete
Jul 27 '08 #131


"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
On Thu, 24 Jul 2008 15:17:05 -0700, Ben Voigt [C++ MVP]
<rb*@nospam.nospamwrote:
>The C# way is brittle. If C# let you use a using statement with types
that
don't support IDisposable, then it would be better. But right now,
adding
IDisposable support to an existing class is always an impermissible
breaking
change.

In C++, you can add a destructor without any changes to the code which
references the class.

If C++ didn't have its own brittle behaviors (including limitations on the
use of stack-allocated classes), I might think your point has some merit
here.
C++ has quite a few brittle behaviors, but I'm not sure what you mean by
limitations on the use of stack-allocated classes.

Can you explain what you're talking about?
>
But it does, so I don't.

Pete
Jul 27 '08 #132
On Sat, 26 Jul 2008 20:00:45 -0700, Ben Voigt [C++ MVP]
<rb*@nospam.nospamwrote:
[...]
>>No, in C# it's not possible to create an object that automatically
performs
cleanup when it becomes unreachable.

I never said it was. But nice straw man.

If it isn't possible in C#, then it obviously isn't just a difference of
syntax as you keep insisting, now is it?
If we were talking about whether "it's possible to create an object that
automatically performs cleanup when it becomes unreachable", then your
statement would be relevant. But we weren't. So it's just a straw man.

The fact is, it's not possible in C++ to do that either. So your straw
man is particularly pointless.

But it is fairly indicative of the direction the discussion has gone,
which is to say it's being corrupted into something altogether different
from what I was pointing out. I'm not going to waste my time trying to
argue a point I never made in the first place, nor in trying to drag the
point back to what I _was_ talking about when it's clear that's not what
anyone else really wants to talk about.

Pete
Jul 27 '08 #133
Peter Duniho wrote:
On Sat, 26 Jul 2008 20:00:45 -0700, Ben Voigt [C++ MVP]
<rb*@nospam.nospamwrote:

[...]
If we were talking about whether "it's possible to create an object that
automatically performs cleanup when it becomes unreachable", then your
I think it is. Most objects in C++ are allocated in the way "structs"
are allocated in C# and they get automatically destroyed, if they aren't
reachable anymore.
statement would be relevant. But we weren't. So it's just a straw man.

The fact is, it's not possible in C++ to do that either. So your straw
man is particularly pointless.
In C++ you have heap allocation and about 8 additional different ways to
create an object.

The only allocation type you have to care about freeing in C++ is heap
allocation. The trick in C++ is to use objects not allocated on the heap
to care about the lifetime of the heap allocated ones.
Just like the "using" keyword in C# can be used to control the lifetime
of an object allocated in a control block.

The big difference in C++ is, that I'm not restricted to a control block
and don't have to care about the lifetime of the object, regardless
where I have allocated them. (for heap allocated objects you have to use
smart pointers surely)

It's just a different point of view:

- In C++ an object is responsible to care about it's resources
and free them in the destructor

- In C# the external code is responsible for calling Dispose
to free the resources of an object

-------------------------------------------------------------------

A small example:

List<objectl;
list<objectl;

In C++: l.erase(...) -the object gets automatically destroyed
(if no heap allocated object is used)

In C#: l.remove(...) -the object is not disposed. If you wish
to you have to call it manually

-------------------------------------------------------------------
For allowing the same automatic deallocation of objects in C# like in
C++, in C# you would need:

- Overloading of assignment operator or at least protecting it
- Destructor for structs
Andre
[...]
Pete
Jul 27 '08 #134
In article news:<O#**************@TK2MSFTNGP02.phx.gbl>, Larry Smith wrote:
C++ is significantly more demanding to get right
from a purely mechanical perpsective alone.
C++ is harder, yes ... but is it actually hard in any absolute sense?

Given that your programs will never work correctly if you employ stupid
programmers you are going to have to employ smart people anyway ... so you
might as well let them use powerful tools.

I don't consider that C++ is harder than other languages by a sufficient
degree for that to be any reason not to prefer it over those languages.
There may be other reasons to choose another language over C++ for a
particular project ... but the fact that it is complex should not be one of
them.

If you don't agree with that we shall just have to agree to differ.

Cheers,
Daniel.

Jul 27 '08 #135
>C++ is significantly more demanding to get right
>from a purely mechanical perpsective alone.

C++ is harder, yes ... but is it actually hard in any absolute sense?

Given that your programs will never work correctly if you employ stupid
programmers you are going to have to employ smart people anyway ... so you
might as well let them use powerful tools.

I don't consider that C++ is harder than other languages by a sufficient
degree for that to be any reason not to prefer it over those languages.
There may be other reasons to choose another language over C++ for a
particular project ... but the fact that it is complex should not be one
of
them.
While I believe you honestly see things this way, none of what you've said
stands up to even mild scrutiny.
Jul 27 '08 #136
On Sat, 26 Jul 2008 23:39:58 -0700, Andre Kaufmann
<an*********************@t-online.dewrote:
Peter Duniho wrote:
>On Sat, 26 Jul 2008 20:00:45 -0700, Ben Voigt [C++ MVP]
<rb*@nospam.nospamwrote:
[...]
If we were talking about whether "it's possible to create an object
that automatically performs cleanup when it becomes unreachable", then
your statement would be relevant. [...]

I think it is. Most objects in C++ are allocated in the way "structs"
are allocated in C# and they get automatically destroyed, if they aren't
reachable anymore.
All due respect, C++ (not counting the GC/managed add-ons of C++/CLI)
doesn't even really have the concept of "reachable". So any claim about
what C++ does _when_ something becomes "unreachable" is necessarily wrong,
or at the very least inaccurate.

I appreciate that RAII doesn't exist in C#. But it's just a way of doing
something. It's not the only way, and C# simply has different idioms for
managing resources. _Occasionally_ where those idioms have to interface
with APIs designed for C++ code, there's the appearance of friction. But
in most cases, simply adjust one's approach to the design resolves that,
and where it doesn't, C# still does allow for code that is semantically
equivalent, albeit in a slightly more verbose way.

I understand how tempting it is for people to just assume I don't have a
clue about what I'm saying. I also realize that, having only used C++ for
a decade or so before exploring C#, I may have less C++ experience than
others involved in the discussion. But I have found that C# and its lack
of RAII hasn't impeded my usage of C# one iota, not even when dealing with
code that has to interact with the unmanaged, C/C++-centric paradigms of
the Windows API.

Finally, just as an aside: I find the "smart pointer" example particularly
weak, as reference counting is itself overused and fragile. I suspect
that there are actually lots better examples of using RAII in powerfully
useful ways, and I think those who are so enamored by it would do well to
explore and expound on those examples, rather than sticking to reference
counting.

And with that, I'm done. Thanks for your time and interest.

Pete
Jul 27 '08 #137
Giovanni Dicanio wrote:
The GC is fine for memory resources - it runs a garbage collection process
when under memory pressure.
But, what about non-memory resources (like sockets, textures, files, etc.) ?
I think that GC is designed for memory resources only, and has very little
clue about non-memory resources.

Instead, if you use RAII and a smart pointer (like shared_ptr, or some
intrusive reference count smart pointer) to manage non-memory resources,
they will be released as soon as the ref count becomes 0, making a very
efficient use of precious resources.

Yes, C# is a very well designed language, which incorporates lots of lessons
learned from C++, Java and Visual Basic.
But C# has not discovered destructors yet :)
And it never will.

Experience has shown that even though the C++ way of destructors
will work fine with perfect code, then in practice the apps leaks
resources.

Bad programmers or that the language is too difficult for average
programmers in reality means the same.

Arne
Jul 28 '08 #138
Ben Voigt [C++ MVP] wrote:
C# is just as capable of hanging, leaking memory, and having
non-deterministic behavior as C++.
I don't believe that.

C# has much less undefined and implementation specific behaviors
than C++.

C# has array index checks and no pointers (assuming not using unsafe).

The language is is in general simpler to understand what is going on.

Those hard to find memory overwrites you can get in C/C++ or mysterious
memory leaks is not possible in C#.
And most C# developers have bought the
company line that .NET prevents memory leaks so they haven't the slightest
clue how to begin looking for one.
I agree that most C# developers does not have a clue about how to
find them.

Because they happen so rarely.

For those that know where to look it is usually easy to find, because
the places to look are pretty limited.

Arne
Jul 28 '08 #139
Daniel James wrote:
In article news:<O#**************@TK2MSFTNGP02.phx.gbl>, Larry Smith wrote:
>C++ is significantly more demanding to get right
from a purely mechanical perpsective alone.

C++ is harder, yes ... but is it actually hard in any absolute sense?

Given that your programs will never work correctly if you employ stupid
programmers you are going to have to employ smart people anyway ... so you
might as well let them use powerful tools.
The concept of hiring smart programmers is fundamentally flawed.

The reality is that companies have to hire the programmers they
can get. And that means a few smart, a lot average and a few hopeless.

The hiring only smart does not work at the industry level.

Arne
Jul 28 '08 #140
Ben Voigt [C++ MVP] wrote:
>>static classes - missing
I don't understand this. Are you saying that C# didn't get to use
"static" when declaring a class until 2.0? That doesn't sound right
to me. I'm also not clear on what you mean by "missing" with respect
to Java, since you can effectively create a static class in Java just
as easily in C#.

I must be misunderstanding what you mean by "static classes"...please
elaborate.

Java and C# use the term "static class" in totally different ways. In C#, a
nested class definition provides privileged access to private members of the
parent when properly addressed using a parent reference, and to generic
argument of the parent, but not an instance of the parent. In Java, a
nested class definition creates an "inner class" which is bound to an
instance of the parent, sort of like the closure that C# uses for anonymous
methods. In Java, "static class" is used to create a nested class that
isn't also an "inner class".
I don't think anyone in the discussion was thinking about Java
"static nested class" or "static member class".

They are practically never referenced as just "static class".

Arne
Jul 28 '08 #141
Peter Duniho wrote:
On Sun, 20 Jul 2008 18:55:20 -0700, Arne Vajhøj <ar**@vajhoej.dkwrote:
>The discussion is whether C#'s and Java's ways had split with C# 2.0
features.

The fact that Java does not have Nullable is not an indication of
such a split, because Java does not have any need for Nullable, because
in Java you use the wrapper classes. Different ways of achieving the
same goal.

So why did you include "nullable types" as an example of the "split" of
"C# and Java's ways"? If anything at all, that's an example of
convergence, not divergence.
I did not. I counted it as an area where it was not a split.
>These additions to C# made C# more similar to Java not less similar.

The addition of the Ping class make C# more similar to Java, even though
Java doesn't have that?
No. Ping was counted as an area where there was a split.

Are you sure that you read my post before replying ????
If you're trying to make a point, you're not being very clear about what
point it is you're trying to make. You keep writing things that are
mutually exclusive of each other.
No. You seem not to have read what I posted.
>>>static classes - missing
I don't understand this. Are you saying that C# didn't get to use
"static" when declaring a class until 2.0? That doesn't sound right
to me. I'm also not clear on what you mean by "missing" with respect
to Java, since you can effectively create a static class in Java just
as easily in C#.
I must be misunderstanding what you mean by "static
classes"...please elaborate.

http://www.google.com/search?hl=en&q...=Google+Search

Well, that's the definition I use. So that doesn't represent a change
in C# 2.0 at all. In either C# or Java you can write a static class (a
class with no instance members is by definition a static class). Just
because the keyword gained usage as a class declaration modifier in 2.0
doesn't mean you couldn't static classes in 1.0.
You can write anything in x86 assembler. That does not make Java and C#
syntax irrelevant.

Adding the static keyword as a class modifier adds the capability to
both enforce only static methods and clearly document the intention.

Two plusses.
In addition, you are again confused about what you're trying to
demonstrate. If Java's object wrappers for value types is in fact just
"different ways of achieving the same goal", then so too is simply
defining a class without any instance members just a "different way of
achieving the same goal".
There is a difference. It would make just as much sense for Java to
add static class as for C#. It would not make any sense to add nullable
to Java.
>> Though, since
your list of new features for .NET 2.0 and C# isn't a complete
enumeration anyway, it's not like any count of that particular list
is a useful comparison anyway.

It is a sample of the features.

Then it's useless with respect to measuring the actual differences
between the languages.
????

Samples is used all the time. I don't think they would be if they were
useless.
>As all samples it has some uncertainty, but claiming that a sample
is not useful shows a blatant lack of understanding of statistics.

Claiming that a sample _is_ useful without showing that it's a
statistically significant (large enough sample size) and statistically
correct (sample collected in a statistically random way) sample shows a
blatant lack of understanding of statistics.
It is statistical significant.

And all the readers should have the knowledge to evaluate the validity
of the sample.

So your statement is completely bogus.

Arne
Jul 28 '08 #142
Jon Skeet [C# MVP] wrote:
On Jul 21, 12:49 am, Arne Vajhj <a...@vajhoej.dkwrote:
>>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":

I'll restrict it to language features, as that's what I was talking
about.
It can be very difficult to distinguish between language and library.
>generics - Java got it in 1.5 (and it is not that different)

It's *massively* different. Hugely, vastly different. IMO, of course,
but type erasure is fundamental difference IMO.
>nullable types - Java has had wrapper objects forever

Not the same thing. While I don't like to micro-optimise too often,
the fact that Nullable<Tis still a value type in C# 2 is a big deal.
Likewise the fact that you can deal with *any* nullable type
generically , instead of having to know the wrapper type in advance.
>anonymous methods - Java has anonymous classes

Unwieldy enough to be a real pain, and read-only access to local
variables. As Peter says, the lack of delegates is significant here.
Sure - Java is not exactly like C#, but the Java way is close enough to
the C# way that Java will never implement the C# way in addition to
the Java way.

Well - never say never. I don't think they will.

Arne
Jul 28 '08 #143
Peter Duniho wrote:
On Sun, 20 Jul 2008 22:45:26 -0700, Jon Skeet [C# MVP] <sk***@pobox.com>
wrote:
>No, you couldn't. A static class isn't just "a clas with no instance
members". On the declaration side, when a class is made static the
compiler will *prevent* you from adding instance members. It also
means you don't have any constructors at all, which is impossible in
C# 1 - you get a default constructor if you don't specify any
constructors. [...]

Yes, I understand that. But by making all the members static, and the
constructor private, without any public member to return an instance of
the class, it's still effectively a static class.
That is not good syntax. Syntax should express the purpose of the code.

A private constructor say that this class can only be instantiated
by code inside the class.

A static keyword on the class say that this class only contains
static methods.

The last one is obviously better. So it is not the same.

Whether the change is worth the added complexity or not is
up for debate.

Apparently Hejlsberg said yes and Gosling said no.

That is a true difference in direction.
If Arne were willing to accept these kinds of subtle differences as
legitimate differences, I wouldn't push it. But he isn't (see his
comments about nullable types). If he's happy for something to be "the
same" as long as it effectively behaves the same, then there shouldn't
in his view be any difference between these various ways to do a "static
class".

If anything, I'd say you can get a lot closer to a real C# 2.0 "static
class" in Java than you can to a real "nullable type", but Arne says the
former isn't in Java while the latter is.
It would make perfect sense to add static class to Java. They decided
not to do it. That is a divergence.

It would not make any sense to add nullable to Java. The need is not
there because Java has wrapper types. By adding nullable to C# they
solved a problem Java never had. That is certainly not divergence.
Based on functionality I would even call it convergence.
Of course, further
complicating matters is that Arne _also_ says the latter _isn't_. Which
is very confusing. :)
No it is just you that are confused.

Arne
Jul 28 '08 #144
Jon Skeet [C# MVP] wrote:
On Jul 18, 3:08 pm, "Jon Skeet [C# MVP]" <sk...@pobox.comwrote:
>Indeed, you need the command line option -langversion:linq but to
quote the documentation:

<quote>
This enables the C# 3.0 support. Only a few features of C# 3.0 have
been implemented in the Mono C# compiler, so not everything is
available.
</quote>

Update to this - I've been chatting with Miguel de Icaza recently
(about something else) and he mentioned that the C# 3.0 support is now
actually completed. I'm not sure how much of it has been released yet,
but when Mono 2.0 comes out it should be fully C# 3.0 compliant.
The language is much easier to implement than the library.

I believe they are still missing a lot of .NET 3.5.

Arne
Jul 28 '08 #145
Peter Duniho wrote:
On Sat, 26 Jul 2008 23:39:58 -0700, Andre Kaufmann
<an*********************@t-online.dewrote:

[...]
All due respect, C++ (not counting the GC/managed add-ons of C++/CLI)
doesn't even really have the concept of "reachable". So any claim about
what C++ does _when_ something becomes "unreachable" is necessarily
wrong, or at the very least inaccurate.

I haven't assumed that you don't have any clue about C++, if you had the
impression then please apologize - wasn't my intention. I have over 15
years C/C++ experience and we currently seem to have just a different
view point.

But C++ has >IMHO< a concept of reachable objects:

Stack allocated objects
It's quite different to the "reachable" concept of GC objects, but the
compiler has to track, when the object becomes unreachable (due to
normal program flow or exceptions) and therefore must be destroyed.
I think you mean heap allocated objects have no concept of "reachable" -
for this point I agree with you.

[...]
I understand how tempting it is for people to just assume I don't have a
clue about what I'm saying. I also realize that, having only used C++
As I wrote above, wasn't my intention to assume that.
for a decade or so before exploring C#, I may have less C++ experience
I think you have only a different viewpoint.
than others involved in the discussion. But I have found that C# and
its lack of RAII hasn't impeded my usage of C# one iota, not even when
dealing with code that has to interact with the unmanaged, C/C++-centric
paradigms of the Windows API.
Not generally I agree, but I had big trouble to deal with COM objects,
which had been passed with a high frequency to a C# callback.
Finally, just as an aside: I find the "smart pointer" example
particularly weak, as reference counting is itself overused and
Smart pointer haven't necessarily something to do with reference
pointer, although they are quite common.
And I agree - smart pointers can be error prone. But there is IMHO
simply no other chance of freeing resources directly, but using
reference counting >or< preventing sharing of objects.
And with that, I'm done. Thanks for your time and interest.
Then O.k., for me we should just agree to a different viewpoint.

One final word:

C# is a great productive language. I can live without RAII in C#,
although it would be fine to have it.
Regarding C++ I would have to criticize much more than in C#.
I've been a die hard C++ developer, but after having touched several
other languages I have the impression that other languages may be more
productive for general purpose applications as C++.
At least they are evolving faster and allow to use new concepts of
developing.

To sum it up: Simpler is commonly better
Pete
Andre
Jul 28 '08 #146
Peter Duniho wrote:
[...]
Sorry, have a line to add to my previous post.
Thanks for your time and interest.
Thank you too.
Pete
Andre
Jul 28 '08 #147
Peter Duniho wrote:
[...]
Sorry, have a line to add to my previous post.
Thanks for your time and interest.
Thank you too.
Pete
Andre
Jul 28 '08 #148
Arne Vajhj wrote:
[...]
And it never will.
IMHO it has Dispose, which effectively is the same. But it hasn't a
concept of stack allocated objects, which automatically (would) call
Dispose() / Destructor.
Experience has shown that even though the C++ way of destructors
will work fine with perfect code, then in practice the apps leaks
resources.
I have only one big problem in C#. How do I distinguish if an object
holds resources or not ?

I'm not a C# expert, but the only chance I have to handle this is to
check if the object is derived from IDisposable, automatically or by my
own, looking at the source code.

Automatically is IMHO better, since a used library object may be changed
and hold an resource afterwards I have implemented my code using this
object.

But anyways I have always the feeling to have missed something .e.g.
calling dispose - every time I create a new instance of another object
and holding the pointer in my class.
[...]
Arne
Andre
Jul 28 '08 #149
In article news:<48***********************@news.sunsite.dk>, Arne Vajhj
wrote:
Ben Voigt [C++ MVP] wrote:
C# is just as capable of hanging, leaking memory, and having
non-deterministic behavior as C++.

I don't believe that.
I don't think Ben means that C# is as prone these sorts of errors as
(badly-written) C++ ... just that C# is not by any means free of them,
and C# programmers need to be aware of the problem areas and capable of
dealing with them.
C# has much less undefined and implementation specific behaviors
than C++.
But it still has some ...
C# has array index checks and no pointers (assuming not using unsafe).
So does C++ if you use checked array classes. C doesn't, but that's not
what we're discussing (or it shouldn't be).
The language is is in general simpler to understand what is going on.
That's true. I don't think the difference it makes in usability is
significant -- especially when weighed against the greater expressiveness
of C++ -- but it does make some.
Those hard to find memory overwrites you can get in C/C++ or mysterious
memory leaks is not possible in C#.
C# has its own problems ... and mysterious memory leaks/overwrites
shouldn't happen in C++ either, as long as you use high-level classes
rather than raw pointers and buffers.

You're really criticizing C here, not C++.

Cheers,
Daniel.
Jul 28 '08 #150

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

17 posts views Thread by Rob | last post: by
42 posts views Thread by Bicho Verde | last post: by
55 posts views Thread by Elijah | last post: by
30 posts views Thread by Rhino | last post: by
8 posts views Thread by Hermawih | last post: by
21 posts views Thread by TAM | last post: by
85 posts views Thread by abhi | last post: by
31 posts views Thread by anand devarajan | last post: by
34 posts views Thread by pandit | last post: by
65 posts views Thread by Chris Carlen | last post: by
reply views Thread by zhoujie | last post: by
reply views Thread by suresh191 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.