Allegro.cc - Online Community

Allegro.cc Forums » Off-Topic Ordeals » [C++] I'm Famous!

This thread is locked; no one can reply to it. rss feed Print
 1   2   3 
[C++] I'm Famous!
BAF
Member #2,981
December 2002
avatar

Quote:

So trying to improve this(C++) wonderful language makes a lot of sense to me.

C# is where it's at! :P

Quote:

I won't talk about performance, portability, or syntax. And yes! as we already know, C++ is not an easy subject to master, just like calculus, algebra, physics or any other stuff.

Performance doesn't matter much these days in most applications, there are far more portable languages (run the same binary everywhere), and the syntax sucks (for example, nested templates and the >> issue).

C++ isn't the worst language ever, but there are far better languages out there for a lot of applications.

james_lohr
Member #1,947
February 2002

Stop clumping C and C++ together like that! C will always be great for low-level programming, embedded systems and small high performance based applications. It's C++ that's trying so hard to be so much more and in so doing becoming more monstrous.

Roberto
Member #7,391
June 2006
avatar

One main goal of the C++ language is to produce software that can run as fast as the hardware allows, so the main issue is that such a garbage collector shouldn't use a single cycle of the processor if it is not needed.

I think shared_ptr's are a good solution

Edgar Reynaldo should modify his class to:

class someclass {
  private :
    int baz;
  public :
    void foo(const int& bar) {
      baz = bar;
    }
}

if he wants sc.foo(5) not to be an error.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

You're right , that works now. I forgot a semi-colon to end the class too.

I still don't see why rvalues can't be used as a reference though. The rvalue has to have some place in memory. As long as you don't expect it to stick around , what's the problem?

BAF
Member #2,981
December 2002
avatar

5 is a constant, so how can you reference it in memory? It isn't in memory...

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Perhaps using 5 wasn't the best example.

Take this example from the article Dustin posted.

A&  a_ref3 = A();  // Error!
A&& a_ref4 = A();  // Ok

Why not just make an rvalue reference (&&) behave as if it were just an lvalue reference (&)? What I mean is , why not allow use of rvalue objects through the current lvalue reference methodology? What does disallowing an rvalue reference in the current standard achieve and what does the proposed rvalue reference really do that allowing current rvalue references would not?

Jonny Cook
Member #4,055
November 2003

Quote:

Am I the only insane one who enjoys programming in C/C++ ?

I enjoy programming in C++. But then again, I haven't worked on any large scale programs.

I've never used D, but I imagine that I'd like it as much or more than C++. And I'd program in C# over C++ any day. Java is the only language that I'd prefer to not deal with. And the more I use PHP, the less I like it...

The face of a child can say it all, especially the mouth part of the face.

ImLeftFooted
Member #3,935
October 2003
avatar

Edgar said:

Why not just make an rvalue reference (&&) behave as if it were just an lvalue reference (&)? What I mean is , why not allow use of rvalue objects through the current lvalue reference methodology? What does disallowing an rvalue reference in the current standard achieve and what does the proposed rvalue reference really do that allowing current rvalue references would not?

Consider this example (from the article):

ifstream &&find_and_open_data_file(/* ... */);

...

ifstream data_file = find_and_open_data_file(/* ... */);  // No copies!

Since the data_file goes out of scope inside find_and_open_data_file, it would normally be closed. Since we specified move semantics however, the code functions as expected.

Currently there is no real way to do this type of operation in C++.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

I think I see some of the problems they're trying to solve now, although I still don't quite understand how move operations function at the lowest level - do they just rearrange references? How are they simpler or more effective than an assignment operation that lets the rvalue object go out of scope - well, wait, I guess that's what they actually are, they basically change the scope ownership of the object by allowing a higher level scope to take over management of a lower level object that is about to go out of scope. Is that somewhat accurate?

ImLeftFooted
Member #3,935
October 2003
avatar

Edgar said:

they basically change the scope ownership of the object by allowing a higher level scope to take over management of a lower level object that is about to go out of scope. Is that somewhat accurate?

Yeah, but thats just one application.

Another one is a typical swap operation. Consider Type to be a complex type, one that requires vast resources to copy.

Here is a common swap implementation

void swap(Type& a, Type& b)
{
    Type tmp(a);
    a = b;
    b = tmp;
}

This involves 3 copies.

Now here is the move semantics version:

void swap(Type& a, Type& b)
{
    Type tmp(move(a));
    a = move(b);
    b = move(tmp);
}

This involves 0 copies and has the same result.

SiegeLord
Member #7,827
October 2006
avatar

Err, pardon my ignorance, but wouldn't the whole problem be moot if you used pointers instead of references?

Like this:

Swap(Type ** a, Type ** b)
{
    Type* temp = *a;
    *a = *b;
    *b = temp;
}

Type* a = new Type("1");
Type* b = new Type("2");
Swap(&a, &b);//a is now 2, by is now 1

Also, how do these rvalue references translate to pointer language? The standard reference is just a shortcut way of saying *const iirc (with a whole set of rules associated with that of course). Are these new things now **const? And if not, I think there should be an rvalue pointer as well as an rvalue reference.

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

ImLeftFooted
Member #3,935
October 2003
avatar

SiegeLord, you're on the right track for understanding. One of the differences between a pointer and an rvalue is that the rvalue must follow certain rules regarding scope while a pointer does not respect any.

Consider this example:

ifstream &&find_and_open_data_file(/* ... */);

...

ifstream data_file = find_and_open_data_file(/* ... */);  // No copies!

Try to rewrite the above using pointers, I think you'll find it a bit more awkward.

At the end of the day you can get the job done without move semantics (like we have for decades).

However, move semantics provide amazing relief to those of us who like to enjoy certain paradigms (namely OOP) yet prefer not to pay for them or deal with inelegant complications (like pointers to pointers of objects!).

anonymous
Member #8025
November 2006

std::swap already does for pointers what you have shown. I think the point is that people sometimes want to work with objects.

Of course you could throw some more indirection at it:

Complex a, b;
Complex* pa = &a;
Complex* pb = &b;
swap(pa, pb);
etc

ImLeftFooted
Member #3,935
October 2003
avatar

anonymous said:

I think the point is that people sometimes want to work with objects.

Precisely.

anonymous said:

Of course you could throw some more indirection at it:

The code would have no effect on a or b.

axilmar
Member #1,204
April 2001

ixilom said:

but I still think that those who want to use CG with C++ should make one themselves or use whatever is available and not try to push it into a standard.

I tried. Here is my try to use the Boehm gc in my programs. Unfortunately, there are some major issues that do not allow for using the Boehm gc in applications other than trivial ones (in C++; the situation is better for C).

I also tried to make a garbage collector using special ptr classes. You can find here my draft code for making a collector out of standard C++. But it's slow, and it does not work with threads.

ixilom said:

Size of project IMHO doesn't matter when it comes to handling memory.

When we say 'size', we refer to complexity. Big programs tend to be more complex than smaller ones, but that's not a definitive rule, of course.

James Lohr said:

I'm not qualified to say much on the subject, but I don't see how GC can ever be implemented without a performance hit (although you've spoken about optimal GC so maybe I'm wrong).

Actually, GC may speed things up! Java allocation is way faster than C++ allocation. I've made some benchmarks in the context of Boehm's gc, and Java is way faster in allocation than C++, except in the case that C++ uses the same algorithm as in Java (i.e. increasing a pointer).

James Lohr said:

For a large project that really needs performance for some bits, it would be safer to do most of it in C#

But it's not my choice. Our clients demand C++. Our managers want C++, and they want to show that we can do it. If it was on me, I would choose Java (because our projects could be run on Linux in the future).

Matthew Leverton said:

I don't care enough to be as nearly informed on the topic as, say axilmar, so my opinion really isn't worth anything from a technical perspective, but it appears that he wants to address the root of the problem as opposed to addressing a symptom with some more obscure syntax. (Which is good.)

Indeed, that's what I am trying to do. I agree with the rest of your comments.

Dustin Dettmer said:

To say the industry shares your stance is silly. It only takes 1 person in the industry to disagree with you and the statement is false. Not only do I disagree with you, the vast majority of #C++ on freenode also disagree.

I would agree with you, but unfortunately reality is different.

The Windows Explorer frequently crashed up until recently with segmentation faults.

Firefox has memory leaks and crashes.

Interner Explorer crashes with segmentation faults.

MS Word frequently crashes, again with segmentation faults.

If you search the internet, you will see many issues with big C++ applications. It's not only me.

Dustin Dettmer said:

Let me get this straight... Your solution to the same problem is to double your memory footprint? I fail to see this as a solution... are you sure you understand what move semantics really fixes?

The memory footprint is not doubled when you use GC. A copying GC defragments memory, so you have a lower memory footprint overall. You also have the advantage of better cache coherence.

Between two collections, an application would use more memory, that's true. But it does not matter: this memory will be paged out anyway. The working set of the application would be the same.

Dustin Dettmer said:

Bjarne himself said the code was not meant for the publics' eyes. The code you referenced is designed to illustrate the need in a way veteran C++ coders could easily see. These code chunks are needed to convince the committee to approve changes.

There should be no distinction of code for veterans and non-veterans. Good code should be equally readable by anyone.

Dustin Dettmer said:

Bjarne is not the kind of man to pick an agenda and make up strong arguments for it. He is the kind of man who finds strong arguments and creates an agenda around them.

Where are those strong arguments in favor of GC in C++? I have searched the web thoroughly, but I have not found them. All I found was some comments in the form 'yes, I like it, other members of the C++ standards committee like it, we will see in the future...'

Roberto said:

One main goal of the C++ language is to produce software that can run as fast as the hardware allows, so the main issue is that such a garbage collector shouldn't use a single cycle of the processor if it is not needed.

I think shared_ptr's are a good solution

Those two statements are contradictory! shared ptrs are much slower than garbage collection. If you study the code for boost::shared_ptr, and especially the assembly listings, you will see that a simple shared ptr assignment results in two pages of assembly, where as in GC a simple pointer assignment is 2 lines of assembly code (load from memory to register, store from register to memory).

Edgar Reynaldo said:

think I see some of the problems they're trying to solve now, although I still don't quite understand how move operations function at the lowest level - do they just rearrange references? How are they simpler or more effective than an assignment operation that lets the rvalue object go out of scope - well, wait, I guess that's what they actually are, they basically change the scope ownership of the object by allowing a higher level scope to take over management of a lower level object that is about to go out of scope. Is that somewhat accurate?

Move semantics are exactly like auto_ptr: ownership is transferred to the object destroyed last.

That's a double-edged sword that will byte many in the future. Just like people complained about auto_ptr and it was not used anywhere (except in trivial cases), people will complain in the future about move semantics as well.

Dustin Dettmer said:

Yeah, but thats just one application.

Another one is a typical swap operation. Consider Type to be a complex type, one that requires vast resources to copy.

Here is a common swap implementation

void swap(Type& a, Type& b)
{
Type tmp(a);
a = b;
b = tmp;
}

This involves 3 copies.

Now here is the move semantics version:

void swap(Type& a, Type& b)
{
Type tmp(move(a));
a = move(b);
b = move(tmp);
}

This involves 0 copies and has the same result.

Yeay, they made swap faster. Great! Now if GC was used, swap of pointers would be much faster than this.

The swap example is the typical example of trying to cure the symptom instead of the cause. And it perfectly fits my explanations about copying and moving in my previous post.

Dustin Dettmer said:

However, move semantics provide amazing relief to those of us who like to enjoy certain paradigms (namely OOP) yet prefer not to pay for them or deal with inelegant complications (like pointers to pointers of objects!).

OOP has nothing to do with move semantics. Java, Smalltalk, C#, Ruby are all OOP, yet they have no move semantics.

I think you meant to say 'move semantics provide amazing relief to those of us who like to use objects instead of pointers'. But that's an implementation issue which could be covered without changing the language.

ixilom
Member #7,167
April 2006
avatar

I said:

Size of project IMHO doesn't matter when it comes to handling memory.

axilmar said:

When we say 'size', we refer to complexity. Big programs tend to be more complex than smaller ones, but that's not a definitive rule, of course.

Doesn't make any difference. If you can't keep track of your news and deletes you shouldn't be coding anything complex anyway.
Unfortually there are programmers who can't and are involved in projects like FF, Explorer and other popular programs. But it doesn't mean we need GC in the C++ standard.

___________________________________________
Democracy in Sweden? Not since 2008-Jun-18.
<someone> The lesbians next door bought me a rolex for my birthday.
<someone> I think they misunderstood when I said I wanna watch...

axilmar
Member #1,204
April 2001

ixilom said:

Doesn't make any difference. If you can't keep track of your news and deletes you shouldn't be coding anything complex anyway.
Unfortually there are programmers who can't and are involved in projects like FF, Explorer and other popular programs. But it doesn't mean we need GC in the C++ standard.

Perhaps you are not aware of many factors that can make things difficult.

First of all, source code is never written from scratch except in very rare circumstances. I am still playing with code that started on 1/1/2000. It's very hard to track changes in an old project, because there are things that you might have forgotten. One of the often repeated problems is to delete something somewhere, forgetting that another deletion of the same object happens in another place.

Secondly, projects involve more than one person, and many different persons over the course of time. So, in a large project, it's very difficult to remember everything, and when a person is replaced with another one, some knowledge is usually lost. This lost knowledge shall not include memory management details, otherwise big problems may be created.

Thirdly, managers push for projects to be finished as soon as possible. Not having to manage new/delete, makes life much easier and the development time much shorter.

Forthly, if managing new/deletes manually was enough, then solutions like shared ptrs would not exist. Obviously, some people had problems managing memory and they wanted the solution.

Finally, there are some algorithms that require garbage collection. For example, when referential cycles are involved.

EDIT:

Do you guys know that boost::shared_ptrs are not thread safe? despite what is said here, if you study the code you will see that is possible for a thread to kick in and increase the ref count of an object just before another thread prepares to delete the shared reference count structure.

EDIT2:

boost::shared_ptr instances are not thread safe, but if you don't use the same shared ptr from two different threads, it's ok.

Still, all of this would be unnecessary if C++ had garbage collection.

anonymous
Member #8025
November 2006

Quote:

Quote:

Of course you could throw some more indirection at it:

The code would have no effect on a or b.

I should have added that thereafter you'd access a and b only through pa and pb. Yeah, stupid and error-prone, I know...

ixilom
Member #7,167
April 2006
avatar

axilmar said:

Lots of talk about not keeping track of your news/deletes across projects, codebases and other developers.

Then thats your problem for not documenting/planning correctly. I'm sure a GC would take care of that ::)

axilmar said:

Thirdly, managers push for projects to be finished as soon as possible. Not having to manage new/delete, makes life much easier and the development time much shorter.

Now, thats just scary.

___________________________________________
Democracy in Sweden? Not since 2008-Jun-18.
<someone> The lesbians next door bought me a rolex for my birthday.
<someone> I think they misunderstood when I said I wanna watch...

james_lohr
Member #1,947
February 2002

Quote:

First of all, source code is never written from scratch except in very rare circumstances. I am still playing with code that started on 1/1/2000. It's very hard to track changes in an old project, because there are things that you might have forgotten. One of the often repeated problems is to delete something somewhere, forgetting that another deletion of the same object happens in another place.

Secondly, projects involve more than one person, and many different persons over the course of time. So, in a large project, it's very difficult to remember everything, and when a person is replaced with another one, some knowledge is usually lost. This lost knowledge shall not include memory management details, otherwise big problems may be created.

Maybe the company you work for should start using a decent SCM tool. It sounds like they have no idea of how to manage traceability and auditability.

Arthur Kalliokoski
Second in Command
February 2005
avatar

Quote:

C# is where it's at! :P

Are they paying you to say that?
http://www.oreillynet.com/xml/blog/2007/01/an_interesting_offer.html

They all watch too much MSNBC... they get ideas.

GullRaDriel
Member #3,861
September 2003
avatar

No, Baf sells his bottom for free ya know :-X

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Milan Mimica
Member #3,877
September 2003
avatar

Quote:

Swap(Type ** a, Type ** b)
{
Type* temp = *a;
*a = *b;
*b = temp;
}

This still copies the data (just pointers, but still) around. Move semantics does not copy anything, right?

ImLeftFooted
Member #3,935
October 2003
avatar

Axilmar, for someone who knows so little about this subject you sure talk loud. I do hope people are not mislead.

Milan said:

This still copies the data (just pointers, but still) around. Move semantics does not copy anything, right?

That code is just copying pointers. Since a pointer is such a simple type, moving and copying have the same overhead.

Thomas Fjellstrom
Member #476
June 2000
avatar

The way I'm seeing copy semantics, is its just a language level feature to alias and/or rename symbols, not actualy a machine level action that moves things.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

 1   2   3 


Go to: