There's at least one gaping hole in the RAII paradigm: What if you want to throw an exception during destruction? (Not all resources can be freed without failure.)
This is a valid point. I'm not sure I understand how finally{} can solve it, though -- can you elaborate?
As far as resources which might fail to be freed, these things seem few and far between, and I just try to accept that dealing with those kinds of resources is more complex and error prone than other resources. Not everything is cake, but most of it is.
The problem with reference-counting pointers like boost::shared_ptr is that they introduce additional memory and computation overhead.
This is true. But in an argument about C++ squaring off against some other language, the other language usually also has an equivalent level of overhead. For instance Java GC is not "free."
And of course, no reference-counted solution can ever solve a memory allocation problem that avoids cycles (although I generally try to avoid circular data structures to begin with).
When I use cyclic data structures (which is not often) I just use weak pointers between the objects -- the objects themselves are owned by a supervisor container.
And of course, it's always possible to "leak memory" by simply forgetting to lose a reference to something that you don't need anymore. That's possible in any language.
I suppose I should have been explicitly more humble. I am not claiming that the STL makes me a god. It does, however, eliminate an entire class of bugs. It's not like the only kind of bug in the world is a memory leak. I most definitely still code bugs. Everybody does.
How about you? Under your coding paradigm (whatever it is), do you have some magic method of proving that there are no leaks? Of course I cannot prove it, any more than you can prove a program correct in general, but tools like valgrind, and empirical observation are strong evidence. If you have some method of proving that code is free of memory leaks I would like to hear about it.
What I do know is that this particular style of coding massively reduces the PROBABILITY of a leak. After all, that's really the best you can hope for.
For example in network data processing you might have to read a packet header , check the size then allocate enough memory for the packet and read it in mapping a number of structure pointers onto the character buffer. Try doing that in any efficient way using the STL.
I'm not sure what part of that you think would be hard, or inefficient. Obviously, the STL cannot do everything you could possibly want. However, the core problem here (memory management) is easily solved by using a vector of char to hold the packet's contents. Exactly what difficulty are you imagining?
Wow. I thought I was reading one of my own posts. I also use Python as a prototyping language for projects which will ultimately be done in C++, and I do it with exactly the same kinds of problems you are solving: statistical NLP.
I've found that most NLP algorithms are easily expressed in Python, but it is too slow to apply to realistic corpora. On the other hand, Python can easily translate to C++ (once you've built up some experience and the kit to go along with it) and the time it takes to write Python + C++ probably ends up shorter than trying to begin right away in C++.
As for diseases, there is no earthly disease that kills 100% of its victims, (because such a disease would then itself become extinct).
This is not even mathematically true, much less practically true. If the population of hosts grows at least at the same rate as the spread of the pathogen, then both can continue to survive even with a 100% fatality rate.
Volcanoes do not spew out as much CO2 as you seem to be implying.
Regardless of how much they may or may not be spewing, look at it this way. If you graph atmospheric CO2 concentrations over the past several thousand years, there is an enormous upward trend in recent years. However, there is no matching enormous upward trend in global volcanic activity at that same time. The trend is occurring right now. If the volcanoes are causing it, please tell me which volcanoes they are. Have geologists found a corresponding huge upward trend in volcanism over the same time period? Nope.
It doesn't prove that man is the cause, but it certainly proves that the volcanoes AREN'T.
The DDT ban might have saved bald eagles, but it has killed millions of people from malaria that would have been otherwise prevented. This may seem strange to you, but some of us value human life more than bird life.
Wow -- I had not realized that there were millions of people dying from malaria in the same areas of the world where the bald eagle lives. Was there some mass malaria epidemic in the US in the 1960's that I haven't heard about?
p.s. Personally I don't even consider it real C if you're not using pointers frequently.
What I said certainly does not apply to C.:)
However, w.r.t. C++ I'd like to hear of an example that requires a pointer to be floating around anywhere other than the bottom-most level of code. I am not claiming that real applications can be programmed without pointers, merely that the pointer manipulation can always be relegated to a container layer (e.g. shared_ptr or otherwise) at the very bottom layer of the code. Once you get the fundamental pointer containers right, you never have to write them again.
Is an int 32 or 64 bits? I had better compile a test program and fire up a debugger to find out. OK, since there's no C standard type for "32 bit int", what works on this compiler? Maybe INT32 is defined somewhere?
Why is this such a massive issue? Once you know the size of an integer for a given platform, you're done. You can collect this knowledge in a header file which can be shared between projects. In fact, this has already been done with stdint.h. Your compiler doesn't have stdint.h? Download Paul Hsieh's portable stdint.h -- it's freely available.
This is a non-issue. And anyway, what the hell are you doing that you need to know how big an integer is? You're doing something inherently low-level (being aware of bits, and how many there are of them) and yet you complain that the language is low level? This is bizarre.
There's exactly nothing that you can do with RAII that you can't with a try {} finally {} block, finalisers, and GC.
I don't know what you Java folks are smoking, but it must be good shit when you think that three different concepts replacing a single simple concept is somehow an improvement.
I view having to call erase() to free up the memory consumed by an object in an stl structure that is no longer needed to be a form of manual memory management.
I agree. However, erasure of objects is tightly coupled to the actual algorithm being implemented. It is of course always possible to get the algorithm wrong. Nobody, including me, writes flawless code.
That kind of holier than thou '*I* don't make mistakes' attitude is the reason why we get so many "not mistakes" in the real world. So get off the high horse and start thinking, will you?
Wow. I don't know where the hell this attitude is coming from. I certainly make mistakes. They simply are not of the memory leak or buffer overrun kind. This is not because I'm a genius, it's because I am disciplined enough to adhere to a set of design principles which make these sorts of errors practically impossible.
Right up until the moment that you need to use inheritance, and suddenly you realise that you're screwed, because the only way you can use an STL container with C++'s broken OO is if you're sticking pointers in that container.
This argument is a non sequitur. You seem to be saying that "If you can use A to do X, and you can use B to do X, you should just use B." Uh, okay. Let's flip "A" for "B" in that statement and see what the difference is.
Programs which use STL containers instead of manual memory management are "trivial?" This is news to me.
Avoiding the use of "new" is not the same as avoiding dynamic allocation. You simply let the containers handle it for you. Yes, there are pointers flying around, but they are out of sight, and managed by code that actually does things properly for you.
GC is available for C++, but IMHO inappropriate. One of the great advantages of C++ is that the construction/destruction mechanism, along with automatic variables, gives you absolute control of the lifetime of every single resource. Whereas a garbage collected language like Java gives you absolutely no control over when (if ever) an object is destructed. I think it is a little wacky to give up this total control of object lifetimes in return for such a puny benefit, a benefit which could easily be achieved through C++ resource management techniques like RAII.
And anyway, garbage collection is irrelevant if you never "new" anything in the first place.
I'm not sure why you feel you need to "track memory" in C++. I did an analysis of all the code I've written a year or so ago, and I found that there is approximately one usage of a pointer in every 5700 lines of code (the way I write it, at least).
We have this great stuff called containers and RAII. And for when you absolutely must, must use a pointer, you have boost::scoped_ptr and boost::shared_ptr. I have not coded a memory leak or buffer overrun in C++ in over six years.
The best way to not leak memory is to never allocate it in the first place. The best way to avoid overflowing raw buffers is to not use raw buffers. Use the containers. When you think you can't, think harder.
I'm not talking about generic drugs, where you are actually getting the exact same drug under a generic brand name. I'm talking about chemically different drugs which are similar in function.
For instance, if I was prescribed Allegra for allergies, I could substitute that for a generic (if one exists) at the pharmacy, but I can NOT substitute Zyrtec, which is also an allergy medication but a completely different compound. What I'm suggesting is that I be allowed to do this, within certain reasonable boundaries. In other words, divide drugs into "equivalent classes" and allow the patient to select the specific drug from the class, obviously under supervision from the doctor.
Gates was spanked hard during the monopoly case. In some of his depositions he was reduced almost to tears at several points. He became a shaking, goofy, childish mess. Not coincidentally, this was around the same time he turned philanthropist, probably in an effort to assuage his guilty conscience.
At least he's capable of feeling guilt, and is, at some level, aware that what he has done is "naughty." This is a huge step past a lot of other slimy businessmen who have perfected the technique of drowning their own conscience.
This assumes that MySQL actually caters to the same user base as more expensive DB software. In reality, the two sets of users hardly overlap at all.
MySQL does not orbit in the same plane as, for example Sybase, nor has it ever been a goal to compete with those products. MySQL is for people who want a database, with available support, who don't want to pay $10,000 for a basic license. In return, MySQL does not provide the magnitude of power as other DB software. This trade-off is perfectly fine.
Wouldn't it be great if the patient had at least SOME degree of control over what is prescribed? Obviously, lay persons should not prescribe drugs for themselves, but if there are three drugs A, B, and C which are all considered roughly equivalent, appropriate treatments for some condition, the patient should be able to decide for him/herself which of the drugs to use.
If I know there is a cheap alternative, and I am willing to take responsibility for my decision, I should be able to request that the alternative be used instead of a more expensive one. Patients can already request a generic substitute, but why not take this just a small step farther and allow them to choose between a set of different, but roughly equivalent drugs.
There's at least one gaping hole in the RAII paradigm: What if you want to throw an exception during destruction? (Not all resources can be freed without failure.)
This is a valid point. I'm not sure I understand how finally{} can solve it, though -- can you elaborate?
As far as resources which might fail to be freed, these things seem few and far between, and I just try to accept that dealing with those kinds of resources is more complex and error prone than other resources. Not everything is cake, but most of it is.
The problem with reference-counting pointers like boost::shared_ptr is that they introduce additional memory and computation overhead.
This is true. But in an argument about C++ squaring off against some other language, the other language usually also has an equivalent level of overhead. For instance Java GC is not "free."
And of course, no reference-counted solution can ever solve a memory allocation problem that avoids cycles (although I generally try to avoid circular data structures to begin with).
When I use cyclic data structures (which is not often) I just use weak pointers between the objects -- the objects themselves are owned by a supervisor container.
And of course, it's always possible to "leak memory" by simply forgetting to lose a reference to something that you don't need anymore. That's possible in any language.
While I have my doubts about your flawless code
I suppose I should have been explicitly more humble. I am not claiming that the STL makes me a god. It does, however, eliminate an entire class of bugs. It's not like the only kind of bug in the world is a memory leak. I most definitely still code bugs. Everybody does.
That you know of.
How about you? Under your coding paradigm (whatever it is), do you have some magic method of proving that there are no leaks? Of course I cannot prove it, any more than you can prove a program correct in general, but tools like valgrind, and empirical observation are strong evidence. If you have some method of proving that code is free of memory leaks I would like to hear about it.
What I do know is that this particular style of coding massively reduces the PROBABILITY of a leak. After all, that's really the best you can hope for.
For example in network data processing you might have to read a packet header , check the size then allocate enough memory for the packet and read it in mapping a number of structure pointers onto the character buffer. Try doing that in any efficient way using the STL.
I'm not sure what part of that you think would be hard, or inefficient. Obviously, the STL cannot do everything you could possibly want. However, the core problem here (memory management) is easily solved by using a vector of char to hold the packet's contents. Exactly what difficulty are you imagining?
Wow. I thought I was reading one of my own posts. I also use Python as a prototyping language for projects which will ultimately be done in C++, and I do it with exactly the same kinds of problems you are solving: statistical NLP.
I've found that most NLP algorithms are easily expressed in Python, but it is too slow to apply to realistic corpora. On the other hand, Python can easily translate to C++ (once you've built up some experience and the kit to go along with it) and the time it takes to write Python + C++ probably ends up shorter than trying to begin right away in C++.
As for diseases, there is no earthly disease that kills 100% of its victims, (because such a disease would then itself become extinct).
This is not even mathematically true, much less practically true. If the population of hosts grows at least at the same rate as the spread of the pathogen, then both can continue to survive even with a 100% fatality rate.
Volcanoes do not spew out as much CO2 as you seem to be implying.
Regardless of how much they may or may not be spewing, look at it this way. If you graph atmospheric CO2 concentrations over the past several thousand years, there is an enormous upward trend in recent years. However, there is no matching enormous upward trend in global volcanic activity at that same time. The trend is occurring right now. If the volcanoes are causing it, please tell me which volcanoes they are. Have geologists found a corresponding huge upward trend in volcanism over the same time period? Nope.
It doesn't prove that man is the cause, but it certainly proves that the volcanoes AREN'T.
The DDT ban might have saved bald eagles, but it has killed millions of people from malaria that would have been otherwise prevented. This may seem strange to you, but some of us value human life more than bird life.
Wow -- I had not realized that there were millions of people dying from malaria in the same areas of the world where the bald eagle lives. Was there some mass malaria epidemic in the US in the 1960's that I haven't heard about?
p.s. Personally I don't even consider it real C if you're not using pointers frequently.
What I said certainly does not apply to C. :)
However, w.r.t. C++ I'd like to hear of an example that requires a pointer to be floating around anywhere other than the bottom-most level of code. I am not claiming that real applications can be programmed without pointers, merely that the pointer manipulation can always be relegated to a container layer (e.g. shared_ptr or otherwise) at the very bottom layer of the code. Once you get the fundamental pointer containers right, you never have to write them again.
Is an int 32 or 64 bits? I had better compile a test program and fire up a debugger to find out. OK, since there's no C standard type for "32 bit int", what works on this compiler? Maybe INT32 is defined somewhere?
Why is this such a massive issue? Once you know the size of an integer for a given platform, you're done. You can collect this knowledge in a header file which can be shared between projects. In fact, this has already been done with stdint.h. Your compiler doesn't have stdint.h? Download Paul Hsieh's portable stdint.h -- it's freely available.
This is a non-issue. And anyway, what the hell are you doing that you need to know how big an integer is? You're doing something inherently low-level (being aware of bits, and how many there are of them) and yet you complain that the language is low level? This is bizarre.
There's exactly nothing that you can do with RAII that you can't with a try {} finally {} block, finalisers, and GC.
I don't know what you Java folks are smoking, but it must be good shit when you think that three different concepts replacing a single simple concept is somehow an improvement.
I view having to call erase() to free up the memory consumed by an object in an stl structure that is no longer needed to be a form of manual memory management.
I agree. However, erasure of objects is tightly coupled to the actual algorithm being implemented. It is of course always possible to get the algorithm wrong. Nobody, including me, writes flawless code.
That kind of holier than thou '*I* don't make mistakes' attitude is the reason why we get so many "not mistakes" in the real world. So get off the high horse and start thinking, will you?
Wow. I don't know where the hell this attitude is coming from. I certainly make mistakes. They simply are not of the memory leak or buffer overrun kind. This is not because I'm a genius, it's because I am disciplined enough to adhere to a set of design principles which make these sorts of errors practically impossible.
Right up until the moment that you need to use inheritance, and suddenly you realise that you're screwed, because the only way you can use an STL container with C++'s broken OO is if you're sticking pointers in that container.
boost::shared_ptr. Problem solved.
This argument is a non sequitur. You seem to be saying that "If you can use A to do X, and you can use B to do X, you should just use B." Uh, okay. Let's flip "A" for "B" in that statement and see what the difference is.
Programs which use STL containers instead of manual memory management are "trivial?" This is news to me.
Avoiding the use of "new" is not the same as avoiding dynamic allocation. You simply let the containers handle it for you. Yes, there are pointers flying around, but they are out of sight, and managed by code that actually does things properly for you.
GC is available for C++, but IMHO inappropriate. One of the great advantages of C++ is that the construction/destruction mechanism, along with automatic variables, gives you absolute control of the lifetime of every single resource. Whereas a garbage collected language like Java gives you absolutely no control over when (if ever) an object is destructed. I think it is a little wacky to give up this total control of object lifetimes in return for such a puny benefit, a benefit which could easily be achieved through C++ resource management techniques like RAII.
And anyway, garbage collection is irrelevant if you never "new" anything in the first place.
I'm not sure why you feel you need to "track memory" in C++. I did an analysis of all the code I've written a year or so ago, and I found that there is approximately one usage of a pointer in every 5700 lines of code (the way I write it, at least).
We have this great stuff called containers and RAII. And for when you absolutely must, must use a pointer, you have boost::scoped_ptr and boost::shared_ptr. I have not coded a memory leak or buffer overrun in C++ in over six years.
The best way to not leak memory is to never allocate it in the first place. The best way to avoid overflowing raw buffers is to not use raw buffers. Use the containers. When you think you can't, think harder.
I'm not talking about generic drugs, where you are actually getting the exact same drug under a generic brand name. I'm talking about chemically different drugs which are similar in function.
For instance, if I was prescribed Allegra for allergies, I could substitute that for a generic (if one exists) at the pharmacy, but I can NOT substitute Zyrtec, which is also an allergy medication but a completely different compound. What I'm suggesting is that I be allowed to do this, within certain reasonable boundaries. In other words, divide drugs into "equivalent classes" and allow the patient to select the specific drug from the class, obviously under supervision from the doctor.
Gates was spanked hard during the monopoly case. In some of his depositions he was reduced almost to tears at several points. He became a shaking, goofy, childish mess. Not coincidentally, this was around the same time he turned philanthropist, probably in an effort to assuage his guilty conscience.
At least he's capable of feeling guilt, and is, at some level, aware that what he has done is "naughty." This is a huge step past a lot of other slimy businessmen who have perfected the technique of drowning their own conscience.
This assumes that MySQL actually caters to the same user base as more expensive DB software. In reality, the two sets of users hardly overlap at all.
MySQL does not orbit in the same plane as, for example Sybase, nor has it ever been a goal to compete with those products. MySQL is for people who want a database, with available support, who don't want to pay $10,000 for a basic license. In return, MySQL does not provide the magnitude of power as other DB software. This trade-off is perfectly fine.
Wouldn't it be great if the patient had at least SOME degree of control over what is prescribed? Obviously, lay persons should not prescribe drugs for themselves, but if there are three drugs A, B, and C which are all considered roughly equivalent, appropriate treatments for some condition, the patient should be able to decide for him/herself which of the drugs to use.
If I know there is a cheap alternative, and I am willing to take responsibility for my decision, I should be able to request that the alternative be used instead of a more expensive one. Patients can already request a generic substitute, but why not take this just a small step farther and allow them to choose between a set of different, but roughly equivalent drugs.
One word: Radial. Two more words: Floating block.
Yeah. I remember the last time I lost $180 thousand trillion. Man, that sucked.
A pentagon is not symmetrical? You have a strange definition of symmetry.