Prev: Deriving from a class derived from a CDialog
Next: How to show underlined menu shortcut letters by default for a contextmenu ?
From: RB on 23 Jun 2010 10:58 > Ugh. Can't you get a more recent compiler? VC6 - ugh! Yea, I can relate to your frustration from a teaching standpoint. And to infuriate you more, I do now own VC 2005 Pro but have not used it much. I am developing all functional apps on the 2005 but still use the VC6 for experimenting because I am so used to it. Actually other than it's total inability to do a lot of STL items and lack of strsafe items, I actually like it. But yes I must and will move on to 2005 totally soon. > About DEL_ON_EXIT: I made it for myself a long time ago, > .........Here it is: Thanks, I'm going put this into VC and step thru it a few times so I can get the full impact of it. Later...........RB
From: Joseph M. Newcomer on 23 Jun 2010 11:00 Well, we were not discussing .NET exceptions, we were discussing C++ exceptions. Since I had never heard of either Parse or TryParse, there was no easy way to detect these were something in .NET and not in some part of C++ I had not seen. I have no data on .NET exception handling. As you point out, if you have a lot of really bad input, why is it really bad input? I would have applied a Parse operation to something vastly more complex than an integer (e.g., an entire script), in which case an exception makes more sense. I had no idea it applied to concepts as trivial as just parsing numbers. joe On Wed, 23 Jun 2010 03:11:04 -0700 (PDT), Goran <goran.pusic(a)gmail.com> wrote: >On Jun 23, 6:02�am, Joseph M. Newcomer <newco...(a)flounder.com> wrote: >> Again, the question is performance: if you had to open a file, read data in, and finally >> invoke the parsing, what percentage of the time is spent handling an exception. > >Joe, it's true, people have been complaining about said .NET Parse >having considerable impact on performance in at least one place on the >internet, and they were right. They actually went on through the >measurements on their use case (and even wrote their own non-throwing >Parse). > >Problem was that they were batch-processing some files, and some of >them had a lot of ill-formatted numbers in them. So they could measure >that use of Parse made code run two times slower (on their use-case, >and clearly, depending on the percentage of these bad numbers). And >note: they were working with files! In fact, IIRC, initially they saw >that "bad" files took more time to process than "good" files - that's >what ticked it all. > >Of course, question is why did they have all those bad numbers in the >first place, but hey... > >Thing is also that .NET exceptions, like MFC (and VCL) ones, can >really be costly: they are on the heap, they are info-rich (e.g. >there's a CString inside) etc. But despite that, I still say, just >like you: there's no performance problems with exceptions; if there >is, programmer is doing something horribly wrong in 99% of cases ;-). > >And absolutely, programmer does not know, by looking at any non- >trivial the code, where it's slow, too! > >Goran. Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Joseph M. Newcomer on 23 Jun 2010 11:04 See below... On Wed, 23 Jun 2010 10:37:23 +0200, Giovanni Dicanio <giovanniDOTdicanio(a)REMOVEMEgmail.com> wrote: > >On 23/06/2010 01:51, Joseph M. Newcomer wrote: > >> Note that this could be handled as >> >> BOOL TryParse(...args...) >> { >> try >> { >> Parse(...); >> return TRUE; >> } >> catch(..whatever..) >> { >> return FALSE; >> } >> } >> >> It ain't rocket science. And it isn't clear to me how handling the exception results in >> "bad code". > >Sure it isn't (ain't?) rocket science... but do you like a fopen that >throws an exception if the file cannot be opened? No, I prefer one >returning an error code. **** As I said, systems in which APIs throw exceptions are really hard to program. Exceptions make sense when you have deep recursion, and need to unwind an unknown and unknowable amount of recursion all at once. And are an alternative when you have hundreds of calls all of which being to look like if(!f()) return FALSE; **** >The fact that you can't open a file is not an exceptional condition, and >I prefer code like: > > if ( some_open_file_api(...) == error ) > { > ... do what you want... (e.g. create the file, or other stuff...) > } > ... normal flow > >instead of try/catch. > >It was clearly written before: the usefulness of exceptions is inversely >proportional to the number of try/catch you use: if you clutter your >code with lots of try/catch then IMHO you are overusing (abusing) >exceptions. **** So cluttering your code with if-statements is better? I think the point is that we want to write code whose complexity is proportional to the task at hand. **** > >I think exceptions should be used in *exceptional* conditions (like >David wrote before). **** But one can argue that a file-open failure when the file is expected to exist is, in fact, an exceptional case... **** > > >BTW: I like these articles from the OldNewThing blog: > >"Cleaner, more elegant, and wrong" >http://blogs.msdn.com/b/oldnewthing/archive/2004/04/22/118161.aspx > >"Cleaner, more elegant, and harder to recognize" >http://blogs.msdn.com/b/oldnewthing/archive/2005/01/14/352949.aspx > > >Giovanni Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Joseph M. Newcomer on 23 Jun 2010 11:07 We just had a piece of code in this NG that looked like this: HANDLE thread = ::CreateThread(...); if(thread == NULL) ::CloseHandle(thread); DWORD result = ::WaitForSingleObject(thread,...); now how many errors can you find in the above code? Closing a NULL handle? Waiting on a NULL handle? This is one of the problems with the if-statement; it *requires* that you abort the path of execution. An exception does that automatically. As I said, this is all interesting debatable material. joe On Wed, 23 Jun 2010 02:35:16 -0700 (PDT), Goran <goran.pusic(a)gmail.com> wrote: >On Jun 23, 10:37�am, Giovanni Dicanio ><giovanniDOTdica...(a)REMOVEMEgmail.com> wrote: >> Sure it isn't (ain't?) rocket science... but do you like a fopen that >> throws an exception if the file cannot be opened? No, I prefer one >> returning an error code. > >Several major frameworks use throwing file open functions and don't >seem to suffer (I know, I argument by number, which is a logical >fallacy ;-)) > >> The fact that you can't open a file is not an exceptional condition, and >> I prefer code like: >> >> � �if ( some_open_file_api(...) == error ) >> � �{ >> � � � ... do what you want... (e.g. create the file, or other stuff...) >> � �} >> � �... normal flow >> >> instead of try/catch. > >The thing is, IMO: exceptions are not "for exceptional conditions". > >They are a way to structure code in face of conditions that normally >cause it to stop whatever it started doing�. (Normally, these >conditions are errors, but not necessarily.) They allow us to >__structure code__ in a more clear way. > >How is that achieved? Simply by eliminating (out of sight, but not out >of existence, really) a myriad of error paths that do no good except >produce screen garbage. So instead of seeing endless if statements, >you see what code does when it works (and we write the code so that it >works, not to err, don't we?). When you need to see "error" paths, you >look at first enclosing try/catch. When you need to see cleanup code, >you look at destructors of stack objects. > >So... IMO, "exceptionality" of the situation matters very little. It's >what happens in WRT code __structure__ that's important. > >About your file open operation: typically, you work with file like >this: > >open >read/write/rinse/repeat //a lot of code here > >Now... If opening a file fails, "a lot of code here" is dead in the >water. So you have a choice of writing an if to stop said code from >running (if open has error result), or doing nothing to stop said code >(if open throws). And if it throws, you are certain that you'll never >forget said "if", because it was done for you. > >Now, I suggest that you look at your own code and say honestly, when >you open a file and that fails, do you continue? I am pretty much >certain that in majority of cases you don't continue. So why would you >like these "ifs"? > >Goran. > >P.S. I mildly like MFC way of having a choice (throwing CFile ctor and >non-throwing ctor + BOOL Open). 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 23 Jun 2010 11:24
"Hector Santos" <sant9442(a)nospam.gmail.com> wrote in message news:OOPShHuELHA.4504(a)TK2MSFTNGP02.phx.gbl... > Not knowing what are all the possible "error" conditions for the .NET > library, I got into a practice of wrapping try catch around much of the > code blocks but also working in the Try Catch Finally logic where > necessary to return negative or positive results. A good last example was > adding a search logic using the Regular Expression .NET library. > > public bool SearchForums(string sPattern) > { > try > { > > Regex rgx = new Regex(sPattern, RegexOptions.IgnoreCase); > foreach (var forum in ForumsList) > { > MatchCollection matches = rgx.Matches(forum.Description); > if (matches.Count > 0) > { > /// got something > } > } > return true; > } > catch (Exception ex) > { > MessageBox.Show("Regular Expression Error: " + ex.Message); > } > return false > } > > This turned out to be nice because for illegal sPattern syntax the class > throws an exception with detail description of the syntax error. I am glad > it did this and not me and it also became a "help" for the the user and > not something we have to documentation. > You can also set a global unhandled exception handler in your app that will display the message box for all exceptions. This saves you from having to put try/catch in so many places, when all you do in the catch is show the exception's message. BTW, the exception also contains a nice callstack string, so you can dump the call stack in the message box as well! :-) > Today, I believe that exception trapping is a vital necessary design > especially for environments .NET. There is still the issue of > programmings not grasp everything, but the throw exceptions are "better" > or rather design with the intent that developers will use them to provide > non-critical feedback. > > You can get in trouble though when you don't understand the errors. This > last example is a good illustration where an explicit exception catch was > used but was a critical abort failure when implemented in a different way. > > The Windows Live ID SDK has an example implementation where the main > program.cs has a catch for specific exception handler for > > System.IO.FileNotFoundException > > like so: > > using System; > using System.Collections.Generic; > using System.Windows.Forms; > using Microsoft.Win32; > > namespace WindowsLiveIDClientSample > { > static class Program > { > /// <summary> > /// The main entry point for the application. > /// </summary> > [STAThread] > static void Main() > { > Application.EnableVisualStyles(); > Application.SetCompatibleTextRenderingDefault(false); > > try > { > Application.Run(new MainWindow()); > } > //System requirement detection. > catch (System.IO.FileNotFoundException fnfex) > { > //Checking for the absence of the Windows Live Sign-In > Assistant DLL. > if (fnfex.Message.Contains("WindowsLive.ID.Client")) > { > MessageBox.Show("Please install the Windows Live ID > For Client Applications SDK."); > } > else > { > MessageBox.Show(fnfex.Message); > } > } > finally > { > Application.Exit(); > } > } > } > } > > Well, if you isolate this LiveID class into your own library and the > LiveID component was not already installed, then you get an exception that > is not System.IO.FileNotFoundException. > > I learn the hard way that this exception was only correct when the LiveID > assembly was bound to the EXE and not a helper DLL. > > The solution was simple, again, not knowing what are the possible specific > exceptions, I used catch all instead and checked for the "LiveID" string > in the exception message. > To be fair, this same problem would have happened if error codes were returned instead of exceptions thrown. (I.e. you may not understand when and under what circumstances various error codes are returned vs. when and under what circumstances various exceptions are thrown.) It's the same thing. > The sad fact is this - its here. It is what it is, libraries are done > mostly one way now and developers have no choice but get use to it and > learn how to work with it. > For me, exceptions offer a way of stepping back and recovering from "various errors" without tediously checking each step along the way. Theoretically they conserve brain power. But the downside is you give up explicit control that you intrinsically get when you are forced to check error codes with nested if. So you spend at least some of the saved brain power understanding and ensuring you cover the various situations, sometimes by trial and error, as you say. For me becoming a .NET programmer, the main question is, do you want to spend brain power making sure you work well with the framework, or do you want to spend brain power tediously coding each possible little thing in MFC. This is why I say .NET makes MFC look like assembly language, with the advantages and disadvantages of such. -- David |