From: Stephen Howe on
HI

According to
http://msdn.microsoft.com/en-us/library/z325eyx0(VS.80).aspx

it says

If _ATL_NO_EXCEPTIONS is defined, the function causes an assertion failure instead of throwing an exception.

Yet in the header file atldef.h, I see

#ifdef _ATL_NO_EXCEPTIONS
#ifdef _AFX
#error MFC projects cannot define _ATL_NO_EXCEPTIONS
#endif

The online MSDN documentation appears wrong.
You cannot define _ATL_NO_EXCEPTIONS for MFC apps.
So no assertion failure for MFC projects, it wont even compile.

Stephen Howe
From: Joseph M. Newcomer on
Thanks for posting this; I will add it to my list of errors when I finally get a working
FrontPage back (let's just say that the MS licensing mechanism is without a doubt one of
the worst systems I've encountered, because it is clearly designed to prohibit legitimate
users from using the product! And unlike most products, FrontPage doesn't have an
activation mechanism!)
joe

On Thu, 24 Jun 2010 19:15:07 +0100, Stephen Howe <sjhoweATdialDOTpipexDOTcom> wrote:

>HI
>
>According to
>http://msdn.microsoft.com/en-us/library/z325eyx0(VS.80).aspx
>
>it says
>
>If _ATL_NO_EXCEPTIONS is defined, the function causes an assertion failure instead of throwing an exception.
>
>Yet in the header file atldef.h, I see
>
>#ifdef _ATL_NO_EXCEPTIONS
> #ifdef _AFX
> #error MFC projects cannot define _ATL_NO_EXCEPTIONS
> #endif
>
>The online MSDN documentation appears wrong.
>You cannot define _ATL_NO_EXCEPTIONS for MFC apps.
>So no assertion failure for MFC projects, it wont even compile.
>
>Stephen Howe
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Goran on
On Jun 24, 8:15 pm, Stephen Howe <sjhoweATdialDOTpipexDOTcom> wrote:
> HI
>
> According tohttp://msdn.microsoft.com/en-us/library/z325eyx0(VS.80).aspx
>
> it says
>
> If _ATL_NO_EXCEPTIONS is defined, the function causes an assertion failure instead of throwing an exception.
>
> Yet in the header file atldef.h, I see
>
> #ifdef _ATL_NO_EXCEPTIONS
>  #ifdef _AFX
>  #error MFC projects cannot define _ATL_NO_EXCEPTIONS
>  #endif
>
> The online MSDN documentation appears wrong.
> You cannot define _ATL_NO_EXCEPTIONS for MFC apps.
> So no assertion failure for MFC projects, it wont even compile.

Well, isn't that entirely logical? MFC uses exceptions as a matter of
fact. Code that is shared between the two (e.g. CString) uses AtlThrow
to work with standalone ATL, MFC, or both. So if you're using MFC, you
are using the "MFC way" already. You are exploring a dead alley with
this.

You can try _ATL_NO_EXCEPTIONS only without MFC, but, if I am not
mistaken, that will turn any calls to AtlThrow into structured
exception (IOW, a crash) in release builds.

So (again, if I am not mistaken): forget _ATL_NO_EXCEPTIONS
altogether, unless... Unless you stop using essentially most of C++
altogether.

Goran.
From: Giovanni Dicanio on
On 25/06/2010 09:09, Goran wrote:

>> The online MSDN documentation appears wrong.
>> You cannot define _ATL_NO_EXCEPTIONS for MFC apps.
>> So no assertion failure for MFC projects, it wont even compile.
>
> Well, isn't that entirely logical? MFC uses exceptions as a matter of
> fact. Code that is shared between the two (e.g. CString) uses AtlThrow
> to work with standalone ATL, MFC, or both. So if you're using MFC, you
> are using the "MFC way" already. You are exploring a dead alley with
> this.

I agree with Goran's analysis.


> You can try _ATL_NO_EXCEPTIONS only without MFC, but, if I am not
> mistaken, that will turn any calls to AtlThrow into structured
> exception (IOW, a crash) in release builds.

That's correct (at least, this is how I knew it, too).

In fact, reading <atlexcept.h> in VS2010, in the preprocessor #else
branch related to the case of _ATL_NO_EXCEPTIONS defined:

<code>
....
#else // no exception handling

// Throw a CAtlException with th given HRESULT
#if !defined( _ATL_CUSTOM_THROW ) // You can define your own AtlThrow

ATL_NOINLINE inline void WINAPI AtlThrowImpl(_In_ HRESULT hr)
{
ATLTRACE(atlTraceException, 0, _T("AtlThrow: hr = 0x%x\n"), hr );
ATLASSERT( false );
DWORD dwExceptionCode;
switch(hr)
{
case E_OUTOFMEMORY:
dwExceptionCode = STATUS_NO_MEMORY;
break;
default:
dwExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
}
_AtlRaiseException((DWORD)dwExceptionCode);
}
#endif


</code>

And _AtlRaiseException is a function which calls RaiseException, which
in turn raises a structured exception.



> So (again, if I am not mistaken): forget _ATL_NO_EXCEPTIONS
> altogether, unless... Unless you stop using essentially most of C++
> altogether.

Forget _ATL_NO_EXCEPTIONS in MFC projects, but not in ATL projects.
ATL can work without C++ exceptions as well; and in case of
*exceptionally bad* error conditions, structure exceptions are raised,
which is just fine. Sure, this does not work if you mean exceptions as a
way to control program flow (stealing the job to 'if's :)

Giovanni

From: Goran on
On Jun 25, 10:58 am, Giovanni Dicanio
<giovanniDOTdica...(a)REMOVEMEgmail.com> wrote:
> Forget _ATL_NO_EXCEPTIONS in MFC projects, but not in ATL projects.
> ATL can work without C++ exceptions as well; and in case of
> *exceptionally bad* error conditions, structure exceptions are raised,
> which is just fine. Sure, this does not work if you mean exceptions as a
> way to control program flow (stealing the job to 'if's :)

It's true, ultimately, one can use ATL without exceptions. I would
never do that, nor recomment that idea to a good friend ;-).

But, for example, I was thinking, if you do "raw" C++, you use e.g.
STL containers (or std::string). In "raw" C++ context, on OOM,
operator new throws bad_alloc. But on same OOM, AtlThrowImpl will
raise STATUS_NO_MEMORY (for AtlThrow(E_OUTOFMEMORY)). So you get the
worst of both worlds :-). That's why I said you need to drop most of C+
+ if you want to go exceptions-free.

By the way, for that reason, I have (had?) a pure ATL (no MFC) project
where I rig set_new_handler to throw CAtlException(E_OUTOFMEMORY).
That gives me "normal" ATL context, and STL containers are throwing
that instead of bad_alloc. Of course, doing that also means that
__any__ other (standard C++) exception going out of STL containers is
a bug, but that is, in fact easy - if they happen, there indeed is a
bug in code. So for that project, my base exception class is
CAtlException. bad_alloc became CAtlException(E_OUTOFMEMORY). I also
had a derivative that had more info in it, e.g. error text for ATL's
Error function. So all COM-boundary methods (virtually all, there's a
couple trivial prop getters) are in fact:

HRESULT Method(params)
{
try
{
workworkwork();
return S_OK;
}
catch (const CAtlException& e)
{ // Nothrow zone here.
return MyOwnErrorThatCallsATLsError(e);
}
}

It's not me who came up with this idea, I stole it from C++ Builder
(Borland tech people knew their programming, pity about the rest of
the company). There, any new COM-boundary method in ATL projects is
generated like that by the IDE.

Goran.