From: Joseph M. Newcomer on 9 May 2010 19:53 See below... On Sun, 9 May 2010 11:57:54 -0500, "JCO" <someone(a)somewhere.com> wrote: > >Okay you pretty much answered all of my questions. The question you had >about.. >SetCustomerName(strName); >All this does is copy the name to the data member of the class as shown >below >m_strClientName = strName; *** I think this would be a mistake. If I were living in an UpdateData world, I would change it to be UpdateData(<whatever boolean is controls-to-variables>) m_strClientName = strName; UpdateData(<whatever boolean is variables-to-controls>); Just setting the string value doesn't change anything. If I thought this might be called before the controls existed, or after they were destroyed, I would conditionalize the UpdateData calls so they would not be executed until, say, OnInitDialog had completed (a simple BOOL will handle this; set fo FALSE in the constructor and TRUE near the end of OnInitDialog, FALSE again on OnDestroy) **** > >I guess I'm a strong believer in encapsulation... so I use Get & Set >statements to access my private data members. > >Your point to the fact that the size of my app should not matter. It's not >that I think it will be to large for a system to run. I'm just being >mindful of memory size allotted when someone runs the application. I think >that's being respectful. When I run applications that are blotted in size, >it makes me wonder why. I do understand what your point will be.... >Instead of worrying about the program size, I should worry more about the >issues caused from using GetDlgItem() and I should worry about... down the >road when modifications to the program is being made.... which is more >readable. *** Here's the rule: code size never matters; data size will kill you. Code size represents code that MUST be there to do the job, so eliminating it cripples functionality. Data size is something you can control. I've seen people moan about a few pointer variables and then generate 1GB of data! Note that you have to work REALLY HARD to eliminate 4K of code size (1 page) and 1 page is NOTHING in the big picture. Similarly, eliminating a few class variables from your small number of classes will not save a page of heap, and therefore has zero impact on performance. You say eliminating code is "respectful". No. In the Real World, making code that is understandable and maintainable is what is respectful. The end users never see your code, and they do not care if there is an extra page of it somewhere; in fact, they will be hard-pressed to even notice. But the next maintainer (or yourself, a few years from now) will notice if there is obscure code that is hard to understand and maintain. The concept that it is "respectful" of the end user to minimize code suggests that you have your priorities completely wrong. Code never generates "bloat", this is a myth Unixoids saddled us with; and it is because they are a bunch of clueless dweebs that they think that .exe size of the memory size shown by task manager have ANYTHING to do with reality. Actually, the Unix tools don't have much reality in them either, but they assume that the Gospel According To Unix is always The Complete Truth, and when they see equally meaningless numbers in what they think are similar tools in Windows, they freak out because they have never learned anything about software or software performance. Remember, the mantra of Unix: "It doesn't matter if it is right, as long as it is small and fast". I used Unix for 15 years, and in that entire time, the goal was to write code that would run on a PDP-11 (64K max address space), even though we were running on Vaxen with megabytes of memory. So little details like making the program CORRECT were not considered important (we used to have a designation, "BQS", which mean "Berkely Quality Software". Software written late one night by someone at Berkely, tested once on the problem he or she needed to solve, and then put on the distribution tape with < 1K of man page documentation to accompany it) Those of us writing production software realized that if you simply omitted all those annoying pieces of code that added bloat, like error checking code, input parameter checking code, bounds checking of arrays, graceful recovery from internal errors, and other useless stuff like that, you, too, could write BQS. Unfortunately, WE were trained to write CORRECT and ROBUST code for a customer base that could be maintained in the field by tech support people at the end of a phone line, not by other programmers who ran it under the debugger and could read the source to learn the input data requirements. As a product quality manager, I shuddered every time we got a new Unix-only hire, because I knew I was going to spend many painful code reviews explaining that all that extra code was NECESSARY if you were going to build a quality product that didn't fail in the field (example: the Berkeley debugger, cdb, had so many bugs we assigned one of our best programmers to fix it. He fixed over 200 bugs. A few days after he released his new, robust debugger internally, we got an update tape from Berkely, that claimed they had fixed over 200 bugs in cdb. He did a diff of the sources, and found that the overlap between his fixes and their fixes was 3 bugs! And most of his changes were in making it work correctly and not crash while debugging! None of theirs were in these areas!) You write the code you need. Code size DOES NOT MATTER. We are not working in a world of fixed-size EPROMS. It is much more "respectful" of the end user to not allow the program to fail, and to provide a high-quality GUI experience or graphics experience, than to think that they will even notice code size. One time, in a code review of some code I wrote for a customer, the customer complained about the code size of my graphics routines. "They are too big" they said, and requested that I make them smaller, like the original code. I explained that the whole point of them was to reduce the serious flicker problems they had. So they took out all my code and sent the product out. The first thing the beta sites complained about was the fact that the beta had severely reduced the flicker, and it was back in the product release! So they had to put my code back. The program size grew not even by one page, and there was no noticeable lag in the graphics performance. But there was no flicker. Code is there to do a job. The job is not always measurable in terms of simple computation output. If you worry about code size, you will warp your thinking in ways that will result in error-sensitive and/or unmaintainable code. joe **** > >Thanks again. > >"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message >news:ra9cu5pobtap589eighdqkltafp1ll5ckq(a)4ax.com... >> See below... >> On Sat, 8 May 2010 10:57:11 -0500, "JCO" <someone(a)somewhere.com> wrote: >> >>>Joseph, >>>I've read every ones comments and I understand that the UpdateData() can >>>cause issues. If done your way, does this mean you create a control (ctl) >>>variable for every control on your Dialog? This brings me to my next >>>issue: >> **** >> It means I create a control variable for every control I care about. >> That's a different >> statement. For example, for static labels (control ID IDC_STATIC) I don't >> bother to >> create controls. >> **** >>> >>>Which method do you recommend to use? >>>One: //no control variable used >>>CString strName; >>>CEdit *pName = (CEdit*) GetDlgItem(IDC_CUSTOMER_NAME); >> **** >> This sucks. It is inappropriate. >> **** >>> >>>pName->GetWindowTextw(strName); >>>SetCustomerName(strName); >>> >>> >>>Two: //uses control variable >>>CString strName; >>>ctlEditCutomerName.GetWindowTextW(strName); >> **** >> This is the only way I work. Except I would not use GetWindowTextW; that >> is the kind of >> programming error Intellinonsense tends to introduce. I would have called >> GetWindowText. >> **** >>>SetCustomerName(strName); >> **** >> You have not specified what SetCustomerName does, or where it is declared. >> So I can't >> comment on the behavior of this call. >> **** >>> >>>Method two seems easier, however, you must declare the control variable >>>(not >>>shown) which makes your code larger in size (I realize not much). >> **** >> Frankly, if you are worried about this kind of issue, you need to get a >> grip on life. It >> is a completely foolish concern. It means you think code size matters, >> and essentially, >> code size never matters, not when you have a 2GB virtual address space. >> We are no longer >> programming PDP-11 minicomputers with 64K of memory, and such concerns are >> misplaced. >> >> Program like it is 2010, not 1975. >> **** >>>My issue >>>... the Dialog I'm working on has 30 CEditBox. Do I really need to create >>>30 Control Variables (ex ctlCustomerName) plus 30 member variables (ex >>>m_strCutomerName)? If I use the GetDlgItem(), I avoid the 30 Control >>>Variables. >> *** >> Sure. Why not? What possible problem could this cause? The GetDlgItem >> requires a cast, >> which I consider disastrous. Look at any of the dialogs in any of the >> source code I >> have. If I have 60 controls I have 60 control variables, so what? I >> cannot imagine doing >> it any other way. I have one massive dialog that has a couple hundred >> control variables. >> The GetDlgItem method is antiquated, a throwback to Petzold-style C >> programming, and >> error-prone. >> joe >> **** >>> >>>Thanks for your in-depth response to my original question. >>> >>> >>>"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message >>>news:1i44u59hf7o13rrovvkbd5lfgd8fo0q0ke(a)4ax.com... >>>> I am always offering a contrarian opinion on this: I would NEVER, EVER >>>> use >>>> a variable to >>>> hold a value except in some extremely rare and estoteric situations >>>> which >>>> I hardly ever >>>> encounter, so NEVER, EVER is a pretty good characterization of what I >>>> do. >>>> >>>> I make all the variables "control" variables which are just ways to name >>>> the control, and >>>> use methods of those variables to extract the data from the control, >>>> such >>>> as >>>> GetWindowText, GetCheck, GetCurSel, etc. >>>> >>>> I never, ever call UpdateData in a dialog or formview; I think the ONLY >>>> valid times this >>>> is called is when the framework calls them before OnInitDialog or after >>>> OnOK is called, >>>> and 99% of the time, I never use this capability either. I seriously >>>> preach that the >>>> whole DDX mechanism should not be used, EXCEPT for DDX_Control that >>>> binds >>>> controls to >>>> variables, and the entire DDV mechanism should be ignored completely, in >>>> favor of >>>> intelligent real-time input validation. >>>> >>>> I generally react to code that arrives on my desk by removing all these >>>> variables and >>>> removing all UpdateData calls, and replacing them with what I consider >>>> sane and robust >>>> code. I allow ONLY control variables to exist. >>>> On Wed, 5 May 2010 14:23:35 -0500, "JCO" <someone(a)somewhere.com> wrote: >>>> >>>>>I have a general question concerning members of class and assigning the >>>>>content. Particularly if I have a class that, for instance has an >>>>>EditBox. >>>>>If I use the Wizard, I can create a member data of type "Control" or >>>>>"Variable". If I choose variable, the wizard does it's thing. Is this >>>>>variable simply used as a conduit? Should it be used simply to set my >>>>>actual data member that I created manually in my Class? Example. >>>>>m_editClientName was created from the Wizard as type variable CString. >>>>>m_strClientName was created by me as part of my private class member. >>>>> >>>>>Code: >>>>>UpdateData(true); >>>> **** >>>> You can tell this was designed by an amateur because UpdateData takes an >>>> argument, true or >>>> false, to indicate the direction of flow. If anything resembling >>>> intelligent design was >>>> used, there would have been methods called ControlsToVariables and >>>> VariablesToControls, >>>> instead of the non-mnemonic 'true' and 'false' options of UpdateData. >>>> You >>>> can always tell >>>> bad design because it exhibits pathologies like this. I never liked it >>>> when I first >>>> encountered it, because I had already spent over two decades arguing >>>> against this kind of >>>> design (it is hard to use, highly error-prone, and basically sucks) >>>> ***** >>>>>m_strClientName = m_editClientName; //editbox variable is simply >>>>>a >>>>>conduit to set my my actual member >>>> **** >>>> I would use >>>> m_EditClient.GetWIndowText(m_strClientName); >>>> >>>> which makes it obvious what is going on; there is never a chance that >>>> the >>>> variables and >>>> the controls are out-of-sync. There is only one truth, the truth in the >>>> control. Note >>>> that because I rely on the truth of the control, there is never a need >>>> to >>>> have the string >>>> value kept in a member variable at all! In fact, it is not at all clear >>>> why you wrote the >>>> equivalent of >>>> B = A: >>>> above, because A already has the value and there is no reason to make a >>>> copy of it in B! >>>> ***** >>>>> >>>>>I'm asking the question because sometimes I fill like I'm creating more >>>>>data >>>>>variables than really needs to be. So, is it good practice to do it the >>>>>way >>>>>shown above? In reality (I just didn't show it), my data is private >>>>>and >>>>>I >>>>>use Public "Get" & "Set" statements to get & set the variables. So >>>>>below >>>>>is >>>>>the way I've been doing it. >>>> **** >>>> My opinion: if you have n data variables, you have n-too-many variables. >>>> **** >>>>> >>>>>Code: >>>>>UpdateData(true); >>>>>SetClientsName( m_editClientName ); >>>> **** >>>> It is not clear why you need to do this inside the implementation. Not >>>> that it is bad, >>>> but if the whole point is to copy a private value to a public value, >>>> there >>>> are serious >>>> questions that should be asked, such as why there is even a private copy >>>> at all. >>>>> >>>>>Continued Code: >>>>>MyClass::SetClientsName ( CString strName ) >>>>>{ >>>>> m_strClentName = strName; >>>>>} >>>> **** >>>> What good does it do to set this name in a variable if the variable is >>>> not >>>> transferred to >>>> the control? The whole point of using a setter is that it should >>>> actually >>>> do something to >>>> make this internal copy be the control contents, or the control and the >>>> copy are >>>> out-of-sync and if the user types something we are going to have >>>> problems. >>>> >>>> Note that doing this right is not always easy or straightforward, but >>>> doing it wrong >>>> (UpdateData) is really easy and supported by the framework; so it is >>>> easy >>>> to get wrong. >>>> >>>> None of my dialogs have ever been so trivial as to be able to use >>>> UpdateData. For >>>> example, I want to enable the Dothis button when the edit control is >>>> non-empty. UpdateData >>>> doesn't have any provision for this. >>>> >>>> We really need to have dialogs support the OnUpdateCommandUI mechanism; >>>> but I essentially >>>> do that explicitly with my constraint-based model (see my essay on >>>> dialog >>>> control >>>> management on my MVP Tips site) >>>> joe >>>> **** >>>>> >>>>>Thanks for your response. >>>>> >>>>> >>>>> >>>>> >>>> Joseph M. Newcomer [MVP] >>>> email: newcomer(a)flounder.com >>>> Web: http://www.flounder.com >>>> MVP Tips: http://www.flounder.com/mvp_tips.htm >> Joseph M. Newcomer [MVP] >> email: newcomer(a)flounder.com >> Web: http://www.flounder.com >> MVP Tips: http://www.flounder.com/mvp_tips.htm Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
From: David Ching on 10 May 2010 00:51 "Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message news:c4heu5ho9rba21stbn0plad57bintc39n4(a)4ax.com... > Here's the rule: code size never matters; data size will kill you. Your rule assumes the only thing that matters is machine performance. What is missing is an analysis of lost programmer productivity, missed deadlines, and extra cost due to things like using DDX variables when DDX members would have aided clarity and eliminated nonsensical temporary variables. -- David
From: Joseph M. Newcomer on 10 May 2010 13:03 See below... On Sun, 9 May 2010 21:51:38 -0700, "David Ching" <dc(a)remove-this.dcsoft.com> wrote: >"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message >news:c4heu5ho9rba21stbn0plad57bintc39n4(a)4ax.com... >> Here's the rule: code size never matters; data size will kill you. > >Your rule assumes the only thing that matters is machine performance. What >is missing is an analysis of lost programmer productivity, missed deadlines, >and extra cost due to things like using DDX variables when DDX members would >have aided clarity and eliminated nonsensical temporary variables. **** No. I do not lose productivity to not using DDX; rather, I found that when I started using MFC, I was losing productivity due to its bizarre side effects. In looking at many, many non-working MFC programs over the last 15 years, I find that there are many errors caused by misunderstanding of DDX. For example, did you notice that the first thing I did was grab all the control variables back to their value variables? Most programmers who use UpdateData fail to realize how critical this is. I have found that many programmers make serious errors (and the code ends up on my desk, with the directive "fix the dialogs so they work right") because of failing to really understand UpdateData. Note that if you never use it, lack of understanding of it has no impact on productivity or correctness. joe **** > >-- David > Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
From: David Ching on 10 May 2010 18:52 "Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message news:hsegu55dl5qacvsvugik8gllfg5rphbakr(a)4ax.com... > See below... > On Sun, 9 May 2010 21:51:38 -0700, "David Ching" > <dc(a)remove-this.dcsoft.com> wrote: > >>"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message >>news:c4heu5ho9rba21stbn0plad57bintc39n4(a)4ax.com... >>> Here's the rule: code size never matters; data size will kill you. >> >>Your rule assumes the only thing that matters is machine performance. >>What >>is missing is an analysis of lost programmer productivity, missed >>deadlines, >>and extra cost due to things like using DDX variables when DDX members >>would >>have aided clarity and eliminated nonsensical temporary variables. > **** > No. I do not lose productivity to not using DDX; rather, I found that > when I started > using MFC, I was losing productivity due to its bizarre side effects. Then your rule should be extended to include productivity since the question is whether to use DDX or not. In my mind, when the subject is UI, developer productivity is king (and not anything that you cite), since performance (either memory or CPU) is not the critical path (at least not for typical LOB apps). -- David
From: Joseph M. Newcomer on 10 May 2010 21:46
My concern is not performance, but correctness. I typically write code at the rate of about 200 lines/hour (varies from 170 to 230). I base this on the number of hours I bill and the code size (excluding my standard libraries, which are huge and would push the averages artificially high) I do not seem to lose any productivity to not using DDX. joe On Mon, 10 May 2010 15:52:11 -0700, "David Ching" <dc(a)remove-this.dcsoft.com> wrote: >"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message >news:hsegu55dl5qacvsvugik8gllfg5rphbakr(a)4ax.com... >> See below... >> On Sun, 9 May 2010 21:51:38 -0700, "David Ching" >> <dc(a)remove-this.dcsoft.com> wrote: >> >>>"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message >>>news:c4heu5ho9rba21stbn0plad57bintc39n4(a)4ax.com... >>>> Here's the rule: code size never matters; data size will kill you. >>> >>>Your rule assumes the only thing that matters is machine performance. >>>What >>>is missing is an analysis of lost programmer productivity, missed >>>deadlines, >>>and extra cost due to things like using DDX variables when DDX members >>>would >>>have aided clarity and eliminated nonsensical temporary variables. >> **** >> No. I do not lose productivity to not using DDX; rather, I found that >> when I started >> using MFC, I was losing productivity due to its bizarre side effects. > >Then your rule should be extended to include productivity since the question >is whether to use DDX or not. In my mind, when the subject is UI, developer >productivity is king (and not anything that you cite), since performance >(either memory or CPU) is not the critical path (at least not for typical >LOB apps). > >-- David Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm |