OpenCascade 5.1 and C++ Exceptions...

I noticed that the foundation classes have different preprocessor definitions for the DEBUG and RELEASE configurations on Windows. Specifically, the RELEASE configuration has the "No_Exception" preprocessor symbol defined while DEBUG does not. The result is that the release version of the DLL does not throw exceptions. Is there a good reason for this? In the code that I am writing, I want to see these exceptions getting raised.

Forum supervisor's picture

Hello Ben,

In fact, No_Exception just means that some macros like Raise_If() do
not thow exceptions in Release mode. Thus in Release mode some checks
(like check for array index out of bounds, check for magnitude of
gp_Dir etc) are not performed. This is reasonable because these checks
are mostly intended for debug, and they are not useful in release
version. On the other hand, avoiding these checks improves performance
of the application.

However, system exceptions still can be raised in Release mode by the
OS (such as memory violation, division by zero, etc).

Thus, current implementation has been optimized for a long time and
has been found most efficient. If you need some other behavior you are
always free to set your favorite compiler switches according to your
needs and to rebuild the sources.

Best regards,
Forum supervisor

Cauchy Ding's picture

Hi Supervisor,

NO_EXCEPTION macro exists default in release configuration. I agree with your performance idea, but I think this macro is overused in many occ basic modeling APIs. For example, creating a line segment using two same points, no exception throwed in release version because macro StdFail_NotDone_Raise_if is empty caused by NO_EXCEPTION. In fact, this is a simple error, so I can catch them out of occ kernel. But for API GeomFill_BSplineCurves, it's difficult for us to capture error out of occ kernel, however I can't capture exception in release version also.
It's dilemma. I don't want to remove NO_EXCEPTION in release configuration, but I hope most of modeling APIs can throw modeling related exceptions.
Any suggestion is welcome.

-Ding

Forum supervisor's picture

Hello Ding,

If you like to enable exceptions in Release mode simply do so by removing NO_EXCEPTION definition. We do not think that classifications of kinds of errors you suggest is acceptable because same errors may occur both due to the internal reasons or due to bad logic in the custom code (ex. index range errors).

Alternatively to enabling all exceptions, you may enable just selected types of exceptions by removing NO_EXCEPTION definition and defining additional macros for the types of exceptions you do not want to be raised. To understand the logic of this approach consult the header file of one of the exception types (ex. Standard_DomainError.hxx)

Best regards,
Forum Supervisor

Cauchy Ding's picture

Hi Supervisor,

Thank you very much for your quick and detailed answer. Removing No_Exception in release configuration is a really bad idea. However, I am still worried about the potential bomb caused by this macro. I think robust is more important than performance for me. Anyway, thanks to you again.

-Ding

Roman Lygin's picture

OCC macros *_Raise_If work like assert()'s. They help you to catch invalid situations while you debug but remove this overhead in shipped code.

Consider N/TCollection_Array::operator() for instance:
Standard_OutOfRange_Raise_if((Index < myLowerBound || Index > myUpperBound),NULL);
return ((Array1Item *)myStart)[Index];

If it were not _Raise_if() but just if this would introduce significant overhead which would slow down entire application.
In some complex cases (e.g. BRepBuilderAPI_MakeShape::Shape()) the code will throw exception (Standard_NotDone in that case) in release mode anyway.

In cases where the code is inlined (e.g. in TCollection_Array.lxx) you can influence release mode by defining compiler macro when building your code.

Hope this helps.
Roman
---
opencascade.blogspot.com - the Open CASCADE blog
www.cadexchanger.com - CAD Exchanger, your 3D data translator