Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Dec 17th, 2005, 9:41 PM   #11
grumpy
Programming Guru
 
grumpy's Avatar
 
Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,223
Rep Power: 5 grumpy is on a distinguished road
I don't consider "using namespace std;" as laziness or as defeating the purpose of namespaces. I tend to avoid it because it can introduce ambiguity into code. Ambiguity in code means a lot of problems, including failure to compile (you confuse the compiler).

The reason I don't tend to use "using namespace std;" when posting examples in forums like this one is because some people simply cut and paste code samples written with a "using namespace std;" into a bigger code base. That can trigger compiler errors depending on what other namespaces there are using, what "using" directives are active and what other classes/functions/etc they have defined. And then the person doing that comes back complaining about being misinformed when, in reality, it is because they have used the example in an invalid manner. By avoiding using namespace std; I allow people to cut and paste (should they really want to) and don't have to worry about having to fix up a later mess because they cut and pasted the example in a way that broke their code.

And, yes, I do consider that the many text books that encourage beginners to employ "using namespace std;" are doing a disservice. "using namespace std;" is a directive that works correctly in simple cases used in text books, but tends to trip people up later when they work on larger programming problems with multiple namespaces. The reason is that "using namespace std;" works VERY DIFFERENTLY from the way those textbooks encourage a beginner to think about it.

One technique of effective teaching is to teach part of the truth, and fill in details later. Teaching blatant misinformation that has to be unlearnt later is a much less effective teaching technique, in the long run.
grumpy is offline   Reply With Quote
Old Dec 17th, 2005, 9:55 PM   #12
para
Programmer
 
Join Date: Dec 2005
Posts: 65
Rep Power: 3 para is on a distinguished road
Quote:
Originally Posted by grumpy
Would you care to substantiate that claim, para? What measurements have you done to compare the "overhead" of a class with the overhead of using a simple pointer based solution?
Compiled assembly output. For a class based approach you have additional function calls (CALL) to constructors, which in turn has several operations such as stack modifiations and of course the actual code, then the destructor call (because you are making a copy and not returning by reference). So you have at least two extra function call overheads for this approach. I don't see how you wouldn't have known this though...
A pointer solution is as easy as passing the pointer back to the caller; calling convention will dictate how this is done, either via EAX register or by stack, either way there are FAR less opcodes executed and if you're doing this hundreds of times per second you want this approach.

Quote:
Originally Posted by grumpy
Have you tried using the simple "pointer" approach in a moderate sized project where (say) several hundred different functions use (directly or indirectly) a function like Jessehk's original range() function, with about 3 of them forgetting to deallocate the memory returned (hence causing a memory leak), 2 of them deleting the memory using operator delete rather than operator delete[], and some with complex logic using multiple calls to range(), potentially result in an attempt to release some blocks of memory more than once.
Valgrind is a free memory analysis tool that will show you all leaks, invalid memory reads, invalid memory writes, what lines in the source they occured, and a stack backtrace at that point. There is absolutely no reason any program should have memory leaks if you take the time to fix them with an analysis tool.

Quote:
Originally Posted by grumpy
Have you also evaluated the cost of acquiring a memory analysis tool and the effort of using it to track down the sorts of errors that I've suggested above.
As I said there are free tools that are portable and easy to use. It (quite seriously) takes merely seconds after running it to read the output and learn what line(s) allocate the block that wasn't deallocated, and a short backtrace of how your program got to that point.

I don't know what you keep calling pointers "raw pointers". It seems that you want to spark an argument (trolling?) just because you think an efficient pointer approach (which is completely provable via assembly output) is too "messy". If you code it carefully, it won't be. If you write an application that tosses pointers around like they are nothing, and don't take the time to track what points to what and what has been allocated and what needs to be freed, obviously you are going to have a huge mess. All I'm saying is the pointer approach is the best if you want efficienty, and I honestly don't know how you can call yourself an expert if you didn't know this stuff anyhow. This is C++ 101 information.
para is offline   Reply With Quote
Old Dec 17th, 2005, 10:33 PM   #13
drifter
Programmer
 
drifter's Avatar
 
Join Date: Jul 2004
Location: Halifax, Nova Scotia
Posts: 39
Rep Power: 0 drifter is an unknown quantity at this point
Send a message via ICQ to drifter Send a message via MSN to drifter
@grumpy

kk, thanks for the info!

Always good to learn something new
__________________
Only two things are infinite, the universe and human stupidity, and im not sure about the former.
drifter is offline   Reply With Quote
Old Dec 17th, 2005, 11:32 PM   #14
grumpy
Programming Guru
 
grumpy's Avatar
 
Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,223
Rep Power: 5 grumpy is on a distinguished road
Quote:
Originally Posted by para
Compiled assembly output. For a class based approach you have additional function calls (CALL) to constructors, which in turn has several operations such as stack modifiations and of course the actual code; then the destructor call (because you are making a copy and not returning by reference). So you have at least two extra function call overheads for this approach. I don't see how you wouldn't have known this though...
You haven't looked at assembler code emitted by modern compilers, obviously. There are techniques (particularly inlining of functions) that avoid the need for function call overhead, and some smarter linkers can eliminate such calls without the need for inlining in source code. With template classes, one technical constraint is often that the constructor and destructor are inlined in code, so (ironically) even with a dumb linker, most compilers can eliminate function call overhead with ANY member function of a template class (with the exception of virtual function dispatch, but that's outside our current discussion).

The C++ standard also explicitly allows compilers to avoid creating temporaries if the only means of detecting those temporaries is by tracking constructor and destructor calls. One of the common optimisations that this allows C++ compilers to implement is Return Value Optimisation (RVO), which essentially means they do not create additional temporaries when returning an object from a function. RVO is a VERY basic optimisation for a compiler writer: compiler technologies for several programming languages predating C++ have implement RVO for at least 20 years.

Quote:
Originally Posted by para
A pointer solution is as easy as passing the pointer back to the caller; calling convention will dictate how this is done, either via EAX register or by stack, either way there are FAR less opcodes executed and if you're doing this hundreds of times per second you want this approach.

Valgrind is a free memory analysis tool that will show you all leaks, invalid memory reads, invalid memory writes, what lines in the source they occured, and a stack backtrace at that point. There is absolutely no reason any program should have memory leaks if you take the time to fix them with an analysis tool.
The pointer technique is also one that relies on the caller remembering to release the memory you have given back to them. There is nothing, other than programmer effort, to ensure that happens. And programmer effort is not cheap.

RAII are simple techniques that, among other things, PREVENT memory leaks. I might be slow, but I fail to see how using a tool to find leaks and eliminate them is more effective use of programmer time than using a relatively simple and consistent technique to prevent them in the first place.

And valgrind is also Linux specific. It may sound strange, but some of us actually do development on machines that don't run linux. Not all of those machines have free memory analysis tools available. And, even if we assume everyone runs Linux, there is still an effort for learning the tool and using it.

Quote:
Originally Posted by para
I don't know what you keep calling pointers "raw pointers".
"Raw pointer" is a technical term for a "pointer that contains the actual address of an object". An alternative term for the same thing is "dumb pointer". "Smart pointer" is a technical term for an object that contains a raw pointer and controls both access to the raw pointer and the lifetime of the object it points at.
Quote:
Originally Posted by para
It seems that you want to spark an argument (trolling?) just because you think an efficient pointer approach (which is completely provable via assembly output) is too "messy".
The issue is that I use a different meaning of efficiency, that is based on the whole software development lifecycle. Use of raw pointers can take less machine instructions, but there are cases where hand-crafted code on raw pointers is much less efficient than achieving the same thing using good quality library equivalents (follow the links I gave in an earlier post, and links from those links, for examples). Even if raw pointers make things inherently more efficient, in terms of machine instructions, there is also an offset of needing more programmer effort to get the code running correctly. In practice, in non-trivial software programs, the number one cost driver is programmer effort. One of the most significant wastages of programmer effort is finding coding errors (which means wading through error reports and error logs, stepping through programs with a debugger, and use of various tools to find invalid behaviours). Any technique that reduces the chance of coding errors pays off much more substantially than avoiding a few function calls.

Quote:
Originally Posted by para
If you code it carefully, it won't be. If you write an application that tosses pointers around like they are nothing, and don't take the time to track what points to what and what has been allocated and what needs to be freed, obviously you are going to have a huge mess.
By stating this, you have demonstrated you have only worked on small programs (eg ones that a single person can keep track of). Coding operations with pointers becomes VERY difficult in moderate or large scale programs. Particularly when you have a team of 20 programmers or so all doing things with pointers, in slightly different ways, and passing information using pointers to each other. If programmer A writes code that allocates an object, and passes a pointer to code written by programmer B, which passes it to code written by programmer C which stores the pointer in a cache for 24 hours and then returns it to code written programmer D which must only destroy the object in some circumstances, there is some scope for logic errors to creep in. And, no matter how good your analysis tools are, there will be some challenge in finding them.

Working with pointers is relatively easy if the code that releases dynamically allocated data is written by the programmer who allocated it, and is also relatively easy for data with a short duration. When you start doing non-trivial things (eg data with a long lifetime, complex conditions for allocating and releasing it), the work is more difficult. It gets even more difficult when different programmers write the different parts of the code (eg one allocates the data and does something with it, another programmer does things with it, and yet another eventually releases it).
Quote:
Originally Posted by para
All I'm saying is the pointer approach is the best if you want efficienty, and I honestly don't know how you can call yourself an expert if you didn't know this stuff anyhow. This is C++ 101 information.
Firstly, I have never described myself as an expert. My job has required work on some moderate and large-sized projects and I have seen the type of problems that ensue because of problems with code that looks simple, but really is not. I am simply stating views based on my experience.

Second, you may view this as "C++ 101 information", but it is not. Working with pointers is one of the most common things that C/C++ newbies get in trouble with. And part of the problem is that people like you say you won't get in trouble if you "code carefully", but you have only written programs of (say) a few hundred or [less likely] a few thousand lines of code. A characteristic of such tiny or small programs is that it is possible for a single person to wrap their mind around what the code is doing. And people still get in trouble with pointers on those programs. When the program gets larger, more complex, or there are serious implications when it fails, your platitudes of "code carefully" completely fail to cut the mustard. If the scope of the program is large enough that no one person can wrap their mind around what it does, it is necessary to use techniques that work on such larger systems, are easy to understand (that doesn't necessarily imply easiest to understand), and serve to eliminate errors rather than relying on "careful coding". Fortunately, the techniques that work on large scale systems also work pretty well on small scale systems. Unfortunately, techniques that work on small scale systems often DO NOT scale up to work on larger systems and techniques that are problematical on small systems (eg using raw pointers) scale up into massive problems on larger systems.

Third, there are a lot of case studies where code which uses raw pointers have been compared with functionally equivalent code using the C++ standard library (eg using vectors rather than a new'd array). Yes, there are trade-offs. Efficiency (by which you actually mean run time speed), in practice, is rarely one of them. Most operations with (say) std::vector<int> actually have comparable efficiency to those involving working with a pointer that address a new'd array. Some non-trivial operations (eg sorting, reversing, etc) have actually been proven to do better, because the code written by a professional library implementer is more efficient than the code which a novice would write to achieve the same thing. If you follow the links I gave in an earlier post (and links from those links), you will find some of those case studies.
grumpy is offline   Reply With Quote
Old Dec 18th, 2005, 1:20 AM   #15
Kilo
Expert Programmer
 
Kilo's Avatar
 
Join Date: Nov 2005
Location: In Pink Clam?
Posts: 542
Rep Power: 0 Kilo is an unknown quantity at this point
Send a message via AIM to Kilo
Thanks for the explaination, now i need to work on changing my habit :p
__________________
"When in Rome, Do as the Romans Do"
"Beauty is in the eye of the BEER holder"
"Save your breath your going to need it for your blow up doll later"

SearchLores.org
Kilo is offline   Reply With Quote
Old Dec 18th, 2005, 3:45 AM   #16
zirener
Newbie
 
Join Date: Dec 2005
Location: Space, Tellus, Europe, Norway, Oslo
Posts: 23
Rep Power: 0 zirener is an unknown quantity at this point
Send a message via MSN to zirener
Well, it's also not very wise to have using-directives in header files, sinc those will be included in other files when somebody includes that headerfile. It can save you from a lot of trouble!
__________________
«Don't touch what you can't grab!»
zirener is offline   Reply With Quote
Old Dec 18th, 2005, 5:30 AM   #17
Polyphemus_
Expert Programmer
 
Polyphemus_'s Avatar
 
Join Date: Aug 2005
Location: Rotterdam, the Netherlands
Posts: 942
Rep Power: 4 Polyphemus_ is on a distinguished road
Quote:
Originally Posted by para
All I'm saying is the pointer approach is the best if you want efficienty
The OP asked for code efficienty, and using the pointer approach is not the most efficient for coding.
Polyphemus_ is offline   Reply With Quote
Old Dec 18th, 2005, 6:49 AM   #18
grumpy
Programming Guru
 
grumpy's Avatar
 
Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,223
Rep Power: 5 grumpy is on a distinguished road
Quote:
Originally Posted by Polyphemus_
The OP asked for code efficienty, and using the pointer approach is not the most efficient for coding.
Indeed. The reference to Python (a language which tends to emphasise doing things correctly over doing them efficiently, although it is not particularly inefficient) certainly suggests that.

Given a choice, I'd prefer to have a program that can be built correctly without excessive effort, even if I lose some runtime performance. The idea of a program that generates the wrong results very efficiently, or takes a lot of effort to actually get right, is not particularly appealing.
grumpy is offline   Reply With Quote
Old Dec 18th, 2005, 8:03 AM   #19
Jessehk
The Oblivious One
 
Jessehk's Avatar
 
Join Date: May 2005
Location: Ontario, Canada
Posts: 644
Rep Power: 4 Jessehk is on a distinguished road
Very interested responses to the debate I seem to have indirectly started. I've learned a lot.
__________________
Dr. Zoidberg: [ecstatic] I'm going to a movie... with FRIENDS!
Jessehk is offline   Reply With Quote
Old Dec 18th, 2005, 8:12 AM   #20
Klipt
Hobbyist Programmer
 
Join Date: Dec 2005
Posts: 118
Rep Power: 0 Klipt is an unknown quantity at this point
"Computers are getting faster - people aren't"
Klipt is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 9:31 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC