From: Joseph M. Newcomer on
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".
oje

On Wed, 23 Jun 2010 00:18:49 +0200, Giovanni Dicanio
<giovanniDOTdicanio(a)REMOVEMEgmail.com> wrote:

>On 22/06/2010 23:06, David Ching wrote:
>
>> Exceptions are meant for rarely occurring ERROR conditions (you
>> know, 'exceptional' conditions!), not normal control flow.I once saw a
>> switch statement rewritten as a bunch of thrown exceptions, not a pretty
>> sight.
>
>I do agree with you David.
>
>The Parse vs. TryParse case of .NET comes in my mind: the earlier
>versions of the framework had the Parse method, which threw exceptions
>in case of parsing error. In later versions (since 2.0?) they introduced
>TryParse, which just returned an error code.
>
>Surrounding Parse calls with try/catch blocks produced bad code; instead
>a simple if-check of TryParse return code is much better, IMHO.
>
>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
See below...
On Tue, 22 Jun 2010 18:35:05 -0400, "RB" <NoMail(a)NoSpam> wrote:

>> ***
>> But the point here is that it *has* called the virtual method
>> ReportSaveLoadException. and it return FALSE from OnOpenDocument.
>> ............
>> Because this is a virtual method, you could override it and if calling the parent
>> returned NULL, you could do something useful such as setting the filename to
>> empty. I think this code actually is incorrect, but you can create your own
>> subclass and do whatever you want.
>------------------------------------------
>Hey Joe, this is getting a bit confusing for me. Why would I want to create my
>own subclass to set the filename to empty when the below framwork code
>(that I previously posted ) sets the filename to "untitled" for me which keeps
>me from inadvertly saving and overwriting any previous persistence ? ?
>>> if (!pDocument->OnOpenDocument(lpszPathName))
****
If throwing the exception works, then the answer is, you wouldn't want to do this. But I
thought you said that it didn't solve the problem.
joe
****
>>> {
>>> ........
>>> else
>>> {
>>> SetDefaultTitle(pDocument);
>>>// RB the above sets the filename to "untitled"
>>>...........
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: RB on

> ****
> If throwing the exception works, then the answer is, you wouldn't want to do this.

Oh ok, thanks.

> But I thought you said that it didn't solve the problem.
> ****

No, I said that when I interrupted the "end of file" exception
by inserting a catch ( CException, e )
( which I'm sure was a mistake now) then I lost the mfc cleanup.
But if mfc catches it on it's own without any try / catch on my part
and does all the cleanup and setting the filename to "untitled"
( found all of this out by stepping thru the framework for each
scenario)
And to the dilemma of my file id I found that if I threw the
AfxThrowArchiveException in my if loop (code below)
that it gave me all the same cleanup and reset code said above.

ar >> FID_Read;; // DWORD FID_Read;
if (FID_Read != FileID) // const DWORD FileID;
{ // FileID mismatch
AfxThrowArchiveException(CArchiveException::badIndex, NULL ); //Invalid file format
}
ar >> VerData.Ver >> VerData.CpyRt >> VerData.Corp;
ar.SerializeClass(RUNTIME_CLASS(CMapStringToString));
ExpMap1.Serialize(ar);
/// Also note I put the file id in a const as you told me.
From: RB on
> ****
> As already pointed out, doing a throw directly inside a try is probably not good style.
> Now if you called another function that called a function that called a function that did
> a throw, that makes more sense.

Oh ok, so like if I ,

// declared in CMyDoc.h
const DWORD FileID;

// and in my doc ctor
CMyDoc::CMyDoc( ) : FileID(FILE_ID)
{
VerData.Ver.Format( _T("Version %d.%d.%d.%d"), VERMAJ, VERMIN, VERFIX, BUILDNUM );
VerData.CpyRt = _T(CPY_RT_YR_STR_LITERAL);
}

// and in my doc serialize do,
try
{
DWORD FID_Read;
ar >> FID_Read;;
Check_ID_Match ( FID_Read );
.........
..........
///////////////////////////////////////////////////////////////
void CMyDocClass::Check_ID_Match ( DWORD& Read )
{
if ( Read != FileID)
{ // FileID mismatch
throw new CWhateverDoesTheJob( ByReadingDocsAndOrSteppingThru);
}
}

From: David Ching on
"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message
news:d0j2261qbnp0hepna91efqiiesg126u0st(a)4ax.com...
> 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".
> oje
>

This implementation of TryParse() doesn't solve the problem we were talking
about. The problem is that if an exception is thrown for the common
occurrence of malformed args, the result is it is SLOWNESS! This
implementation would fix this problem:

BOOL TryParse(...args...)
{
if (!IsValid(args))
return FALSE;

Parse(...); // Parse() will not throw because args are valid
return TRUE;
}


-- David