learn C++ or C#

J

Jack Hanebach

Peter said:
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).
 
A

Andre Kaufmann

Peter said:
On Fri, 25 Jul 2008 09:35:20 -0700, Andre Kaufmann

[...]
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 ;-)

Andre
 
B

bjarne

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.
 
L

Larry Smith

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.
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.
 
B

Ben Voigt [C++ MVP]

Peter Duniho said:
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.
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?
 
B

Ben Voigt [C++ MVP]

Peter Duniho said:
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?
 
A

Andre Kaufmann

Peter said:
On Sat, 26 Jul 2008 20:00:45 -0700, Ben Voigt [C++ MVP]

[...]
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<object> l;
list<object> l;

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
 
L

Larry Smith

C++ is significantly more demanding to get right
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.
 
A

Arne Vajhøj

Giovanni said:
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
 
A

Arne Vajhøj

Ben said:
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
 
A

Arne Vajhøj

Daniel said:
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
 
A

Arne Vajhøj

Ben said:
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
 
A

Arne Vajhøj

Peter said:
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.
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.
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.
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.
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
 
A

Arne Vajhøj

Jon said:
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.
It's *massively* different. Hugely, vastly different. IMO, of course,
but type erasure is fundamental difference IMO.


Not the same thing. While I don't like to micro-optimise too often,
the fact that Nullable<T> is 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.


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
 
A

Arne Vajhøj

Peter said:
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
 
A

Arne Vajhøj

Jon said:
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
 
A

Andre Kaufmann

Peter said:
On Sat, 26 Jul 2008 23:39:58 -0700, Andre Kaufmann

[...]
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

Andre
 
A

Andre Kaufmann

Arne said:
[...]
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top