473,787 Members | 2,881 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

"Poll" Has C# Generally Replaced C++

Is it your general opinion that C# is generally designed/intended/ready to
replace C++? I know the answer is not black and white but please repond YES
or NO (add any comments if you would like)

I just thought it might be interesting to get a tally. This is related to a
previous thread. So far we have two NOs from "aa" and Bo Persson.

--
Greg McPherran
www.McPherran.com
Dec 10 '05
71 3185
JAL
Tom... C++/cli has implemented deterministic destructors by implementing the
semantics of a ref class "on the stack." It basically automates the using
construct.

http://www.geocities.com/jeff_louie/...estructors.htm

"Tamas Demjen" wrote:
And I believe C++/CLI
is prepared to deal with those cases too. C# is not. Correct me if I'm
wrong.

Dec 14 '05 #31
JAL
I don't really understand your point. Java and C# are garbage collected and
objects are created using reference semantics.They do not normally use
reference counting so finalization is not deterministic. Seems to me there is
a direct link between the decision to use garbage collection and the lack of
deterministic finalization.

C# value types do not have destructors, but C++/cli ref classes can be
declare "on the stack" so that the "destructor " gets called when the "value"
goes out of scope, much in the way that delete is called on a contained
pointer when the smart pointer goes out of scope.

"Carl Daniel [VC++ MVP]" wrote:
It's really not a consequence of the runtime being garbage collected, but
rather a consequence of the by-reference way in which objects are handled in
C# (or Java). The lifetime of the object is de-coupled from the lifetime of
the reference by the indirection. This can be a "Good Thing" if the object
contains no resources other than memory, but it's a detriment when the
object holds other kinds of resources.


Dec 14 '05 #32
JAL
No... but smart pointers replace the try catch also

void foo()
{
auto_ptr<MyClas s> p(new MyClass);
p->DoSomething( );
}

replaces

void foo()
{
MyClass* p;
try {
p = new MyClass;
p->DoSomething( );
delete p;
}
catch (...) {
delete p;
throw;
}
}

"Tamas Demjen" wrote:
I don't want that. try/catch can't do

std::vector<boo st::shared_ptr< Resource> > items;
Dec 14 '05 #33
JAL wrote:
I don't really understand your point. Java and C# are garbage collected and
objects are created using reference semantics.They do not normally use
reference counting so finalization is not deterministic. Seems to me there is
a direct link between the decision to use garbage collection and the lack of
deterministic finalization.
Regarding memory this is true. But regarding resources (e.g. file
handles) you cannot always rely on garbage collection.

You have to write:
void foo()
{

using ( File f1 = new File(), File f2 = new File())
{
....
} <-- Here the files are automatically closed

}

Would be fairly easy to allow using keyword to be used in a more direct
manner in C#:

void foo()
{
using File f1; // Automatically default constructed
using File f2("aa"); // Automatically constructed
} <-- Here the files would be automatically closed

But this unfortunately doesn't help if you need to have an object in
multiple lists and automatically disposed after the last reference has
been removed from the list.
[...]


Andre
Dec 14 '05 #34

Greg wrote:
int[] x;

x has all the methods of ICollection and Array. So I think int[] x is apples
to apples.


An array in C# is not extensible. A std::vector is....

Arnaud
MVP - VC

Dec 14 '05 #35
JAL wrote:
I don't really understand your point. Java and C# are garbage
collected and objects are created using reference semantics.They do
not normally use reference counting so finalization is not
deterministic. Seems to me there is a direct link between the
decision to use garbage collection and the lack of deterministic
finalization.


Deterministic object lifetime and deterministics memory reclamation are two
separate things. C# joins them into a single concept, but they needn't be
so joined. C++/CLI is an example of a language that treats them as the
separate things that they are.

-cd
Dec 14 '05 #36

"JAL" <JA*@discussion s.microsoft.com > skrev i meddelandet
news:DB******** *************** ***********@mic rosoft.com...
No... but smart pointers replace the try catch also

void foo()
{
auto_ptr<MyClas s> p(new MyClass);
p->DoSomething( );
}

replaces

void foo()
{
MyClass* p;
try {
p = new MyClass;
p->DoSomething( );
delete p;
}
catch (...) {
delete p;
throw;
}
}


Or, if you are using proper C++:

void foo()
{
MyClass m;
m.DoSomething() ;
}
No problem! ;-)
Bo Persson

Dec 14 '05 #37
JAL wrote:
No... but smart pointers replace the try catch also


My point is that the C# using keyword works for trivial cases when you
locally allocate and object and delete it right away. But C# using
doesn't work when the object has a longer life span, but still requires
automatic destruction. How do you store a list of resources in a
container/collection with deterministic cleanup?

All you're showing is that

C++ auto_ptr<T> t(new T)
is the same as
C# using(T t = new T)

That I agree with. But the real differences begin to show up when I can
do in C++ vector<shared_p tr<T> >. In C# I don't think there's a solution
to it. I actually tried to put objects into a List<T> using C# 2.0, and
it didn't automatically call Dispose on T. So List<T>::Dispos e (if it
has such a thing at all) doesn't call Dispose for the contained objects.
I think it would be nice if .NET collections had a Dispose method, which
would call Dispose for its members. But even that wouldn't solve a lot
of other problems that reference counted shared_ptr does. What if a
single resource has 2 object copies, both handling the same resource,
and the actual resource should only be disposed when the last object
copy goes out of existence?

As Carl said, pure managed memory reclamation is not the same thing as
resource reclamation. In C# you don't worry about releasing allocated
managed memory, but you still have the burden of reclaiming resouces,
and the language doesn't provide a very good support for that. The using
keyword only solves that for trivial cases, when the object is create
and delete in the *same scope*, which can't always be ensured. In
complex applications resources are stored in containers, in other
objects, and they're destructed in a very complex way.

One more advantage of the boost implementation is weak_ptr. It clearly
separates ownership semantics (shared_ptr) from reference semantics
(weak_ptr). Using weak_ptr you can be sure that you don't leave trash
objects behind accidentally. It automatically makes sure that when the
last shared_ptr goes out of existence, all weak_ptr's that refer to the
object get NULLed out automatically. I challenge you to implement this
in C#, without manually having to call Dispose. I believe it's doable in
C++/CLI, even if we don't initially have such a solution yet.

I'd like to note that even in C++/CLI the standard .NET containers
suffer from deterministric destruction problems:

using namespace System::Collect ions::Generic;

ref class Guarded
{
public:
~Guarded() { Console::WriteL ine(L"~Guarded" ); }
};

int main(array<Syst em::String ^> ^args)
{
List<Guarded^> items;
items.Add(gcnew Guarded);
return 0;
}

Although "items" uses stack semantics, when it goes out of scope it
doesn't Dispose its members. And trying to do

List<Guarded> items

doesn't work, because List<T> is a generic, not a template. I'm not sure
if the upcoming STL.NET will solve this. It's very concerning when I
program in .NET, even in C++/CLI. I simply can't use the .NET containers
to store objects that wrap unmanaged types, because the Dispose pattern
is broken. I think it's just a matter of time before really good C++/CLI
container implementations come out, where we'll be able to write

vector<shared_p tr<ManagedClass > >

Not having the proper tools for this problem, I feel like I live in
danger, just like C programmers do (whether they admit it or not). Or
even more so, because C programmers are not used to exceptions, but .NET
programmers must think of exception safety. Every system that provides
exceptions but no exception safety is a disaster waiting to happen.

Tom
Dec 14 '05 #38
Some have pointed out advantages of C++ which I don't contest. Yet, I am not
sure these are outweighed by other considerations for many .NET development
scenarios.

There are some cases where C++ is the only option: e.g. a pure native
Windows App with no .NET Runtime required.

However for a .NET app, if C++ is on par with C#, then how does one decide
which language to use. Are there any criteria besides being already familiar
with C++ etc.?

I.e. are there any concrete reasons why the full development cycle right up
to delivery will be more cost effective and yield greater ROI using one
language vs. the other?

Thank You
--
Greg McPherran
www.McPherran.com
"Andre Kaufmann" wrote:
Greg wrote:
Is it your general opinion that C# is generally designed/intended/ready to
replace C++? I know the answer is not black and white but please repond YES
or NO (add any comments if you would like)

I just thought it might be interesting to get a tally. This is related to a
previous thread. So far we have two NOs from "aa" and Bo Persson.


Yes and no.

IMHO C++ - C++/CLI and C# can be used very effectively together and both
languages have their pros and cons.

What about if the C# compiler could freely mix both languages in a
single project e.g. something like 'extern "C++" in C# ;-) and directly
call the C++/CLI code without using an intermediate DLL or linker tricks ?

If additionally C# would have RAII I would be perfectly happy about this
combination.

To be real, I think both languages will coexist for a very long time.
Only if the basis, the operating system and it's main interfaces will be
managed code too and if the native MSIL compiler will be available I
think more and more code will be written in plain C#.

Currently I think C# has another focus than replacing C++. But this may
happen some day.

Andre

Dec 15 '05 #39
JAL
Hi Tom... I agree that using comes up short when compared to smart pointers.
Using is "... about as close as we can get to a smart pointer and RAII in C#"
The best I can do in C# is:

using System;
using System.Collecti ons.Generic;
using System.Text;
using System.Collecti ons;

namespace DeterminedColle ction
{
interface IData
{
int I { get;}
}
interface IMyInterface : IData, IDisposable{}
class Dummy : IMyInterface
{
private bool disposed = false;
private int i;
public Dummy(int i)
{
this.i = i;
}
public void Dispose()
{
Dispose(true);
Console.WriteLi ne("disposed") ;
GC.SuppressFina lize(this);
}
private void Dispose(bool disposing)
{
if (!this.disposed )
{
if (disposing) // called from Dispose
{
// Dispose managed resources.
}
// Clean up unmanaged resources here.
}
disposed = true;
}
~Dummy() // maps to finalize
{
Dispose(false);
}
public int I {
get {
if (disposed) { throw new ObjectDisposedE xception("Dummy "); }
return i;
}
}
}
class JALCollection : IDisposable //, IEnumerator
{
private bool disposed = false;
private ArrayList list = new ArrayList();
// ASSERT d is not null
// ASSERT no object holds a reference to
// d outside of this class
// USAGE Add(new MyClass());
// where MyClass implements IMyInterface
public void Add(IMyInterfac e d) {
if (d != null)
{
list.Add(d);
}
else { throw new ArgumentExcepti on(); }
}
// test only, not safe! implement IEnumerator
public int GetValue(int i)
{
return ((IData)list[i]).I;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFina lize(this);
foreach (IDisposable d in list)
{
d.Dispose();
}
}
private void Dispose(bool disposing)
{
if (!this.disposed )
{
if (disposing) // called from Dispose
{
// Dispose managed resources.
}
// Clean up unmanaged resources here.
}
disposed = true;
}
~JALCollection( ) // maps to finalize
{
Dispose(false);
}
}
class Program
{
static void Main(string[] args)
{
using (JALCollection jal= new JALCollection() )
{
jal.Add(new Dummy(1));
Console.WriteLi ne(jal.GetValue (0)); // test only
}
Console.ReadLin e();
}
}
}

Dec 15 '05 #40

This thread has been closed and replies have been disabled. Please start a new discussion.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.