ExceptionMacros.h File Reference


Detailed Description

This file contains macros which are convenient to use for sprinkling error checking around liberally in SimTK programs, a practice which is highly encouraged.

You can think of this as a generalization of the standard assert() macro. By default, these macros evaporate completely in a release build, but are present in any debug build. Macros are also provided which are always present in cases where the error checking is not a performance problem, and those should be used in preference to the disappearing ones when appropriate. Also, you can force the disappearing macros to remain present on a file-by-file basis, primarily for use in debugging those annoying problems which only occur in release builds and won't reproduce in a debug build.

Most macros have a similar structure, something like this: SimTK_MACRONAME[nargs][_ALWAYS](printfString [, args...]) for example SimTK_ASSERT3("expected %d < count < %d but count=%d", lower, upper, count); or SimTK_ASSERT3_ALWAYS("expected %d < count < %d but count=%d", lower, upper, count); In addition to disappearing without a trace, these macros will also capture the current file name and line number for reporting to developers when appropriate.

Note that these are *global* symbols, so we use the reserved SimTK_ name prefix (since we can't use the SimTK:: namespace for macros) to attempt to avoid pollution of user programs.

We distinguish between macros which are used as internal "bugcatchers" and those which are used to report errors to API users. The C++ exception mechanism is used in both circumstances but the meaning and intended audience is quite different. Any macro with 'ASSERT' in the name represents an internal error which cannot be attributed to user misbehavior. Otherwise these are for communicating with users. Those need to be carefully documented so that users can selectively catch the exceptions when appropriate.

#include "SimTKcommon/internal/common.h"
#include "SimTKcommon/internal/Exception.h"
#include <string>
#include <iostream>
#include <exception>

Go to the source code of this file.

Defines

#define SimTK_INDEXCHECK_ALWAYS(lb, ix, ub, where)
#define SimTK_SIZECHECK_ALWAYS(sz, maxsz, where)
#define SimTK_SIZECHECK_NONNEG_ALWAYS(sz, where)
#define SimTK_VALUECHECK_ALWAYS(lb, val, ub, valName, where)
#define SimTK_VALUECHECK_NONNEG_ALWAYS(val, valName, where)
#define SimTK_APIARGCHECK_ALWAYS(cond, className, methodName, msg)
#define SimTK_APIARGCHECK1_ALWAYS(cond, className, methodName, fmt, a1)
#define SimTK_APIARGCHECK2_ALWAYS(cond, className, methodName, fmt, a1, a2)
#define SimTK_APIARGCHECK3_ALWAYS(cond, className, methodName, fmt, a1, a2, a3)
#define SimTK_APIARGCHECK4_ALWAYS(cond, className, methodName, fmt, a1, a2, a3, a4)
#define SimTK_APIARGCHECK5_ALWAYS(cond, className, methodName, fmt, a1, a2, a3, a4, a5)
#define SimTK_INDEXCHECK(lb, ix, ub, where)   SimTK_INDEXCHECK_ALWAYS(lb,ix,ub,where)
#define SimTK_SIZECHECK(sz, maxsz, where)   SimTK_SIZECHECK_ALWAYS(sz,maxsz,where)
#define SimTK_SIZECHECK_NONNEG(sz, where)   SimTK_SIZECHECK_NONNEG_ALWAYS(sz,where)
#define SimTK_VALUECHECK(lb, val, ub, valName, where)   SimTK_VALUECHECK_ALWAYS(lb,val,ub,valName,where)
#define SimTK_VALUECHECK_NONNEG(val, valName, where)   SimTK_VALUECHECK_NONNEG_ALWAYS(val,valName,where)
#define SimTK_APIARGCHECK(cond, className, methodName, msg)   SimTK_APIARGCHECK_ALWAYS(cond,className,methodName,msg)
#define SimTK_APIARGCHECK1(cond, className, methodName, fmt, a1)   SimTK_APIARGCHECK1_ALWAYS(cond,className,methodName,fmt,a1)
#define SimTK_APIARGCHECK2(cond, className, methodName, fmt, a1, a2)   SimTK_APIARGCHECK2_ALWAYS(cond,className,methodName,fmt,a1,a2)
#define SimTK_APIARGCHECK3(cond, className, methodName, fmt, a1, a2, a3)   SimTK_APIARGCHECK3_ALWAYS(cond,className,methodName,fmt,a1,a2,a3)
#define SimTK_APIARGCHECK4(cond, className, methodName, fmt, a1, a2, a3, a4)   SimTK_APIARGCHECK4_ALWAYS(cond,className,methodName,fmt,a1,a2,a3,a4)
#define SimTK_APIARGCHECK5(cond, className, methodName, fmt, a1, a2, a3, a4, a5)   SimTK_APIARGCHECK5_ALWAYS(cond,className,methodName,fmt,a1,a2,a3,a4,a5)
#define SimTK_STAGECHECK_TOPOLOGY_REALIZED_ALWAYS(cond, objType, objName, methodNm)
#define SimTK_STAGECHECK_EQ_ALWAYS(currentStage, targetStage, methodNm)
#define SimTK_STAGECHECK_GE_ALWAYS(currentStage, targetStage, methodNm)
#define SimTK_STAGECHECK_LT_ALWAYS(currentStage, targetStage, methodNm)
#define SimTK_STAGECHECK_RANGE_ALWAYS(lower, current, upper, methodNm)
#define SimTK_STAGECHECK_TOPOLOGY_REALIZED(cond, objType, objName, methodName)   SimTK_STAGECHECK_TOPOLOGY_REALIZED_ALWAYS(cond,objType,objName,methodName)
#define SimTK_STAGECHECK_EQ(currentStage, targetStage, methodNm)   SimTK_STAGECHECK_EQ_ALWAYS(currentStage,targetStage,methodNm)
#define SimTK_STAGECHECK_GE(currentStage, targetStage, methodNm)   SimTK_STAGECHECK_GE_ALWAYS(currentStage,targetStage,methodNm)
#define SimTK_STAGECHECK_LE(currentStage, targetStage, methodNm)   SimTK_STAGECHECK_LE_ALWAYS(currentStage,targetStage,methodNm)
#define SimTK_STAGECHECK_RANGE(lower, current, upper, methodNm)   SimTK_STAGECHECK_RANGE_ALWAYS(lower,current,upper,methodNm)
#define SimTK_ASSERT_ALWAYS(cond, msg)   do{if(!(cond))SimTK_THROW2(SimTK::Exception::Assert,#cond,(msg));}while(false)
#define SimTK_ASSERT1_ALWAYS(cond, msg, a1)   do{if(!(cond))SimTK_THROW3(SimTK::Exception::Assert,#cond,(msg),(a1));}while(false)
#define SimTK_ASSERT2_ALWAYS(cond, msg, a1, a2)   do{if(!(cond))SimTK_THROW4(SimTK::Exception::Assert,#cond,(msg),(a1),(a2));}while(false)
#define SimTK_ASSERT3_ALWAYS(cond, msg, a1, a2, a3)   do{if(!(cond))SimTK_THROW5(SimTK::Exception::Assert,#cond,(msg),(a1),(a2),(a3));}while(false)
#define SimTK_ASSERT4_ALWAYS(cond, msg, a1, a2, a3, a4)   do{if(!(cond))SimTK_THROW6(SimTK::Exception::Assert,#cond,(msg),(a1),(a2),(a3),(a4));}while(false)
#define SimTK_ASSERT(cond, msg)   SimTK_ASSERT_ALWAYS(cond,msg)
#define SimTK_ASSERT1(cond, msg, a1)   SimTK_ASSERT1_ALWAYS(cond,msg,a1)
#define SimTK_ASSERT2(cond, msg, a1, a2)   SimTK_ASSERT2_ALWAYS(cond,msg,a1,a2)
#define SimTK_ASSERT3(cond, msg, a1, a2, a3)   SimTK_ASSERT3_ALWAYS(cond,msg,a1,a2,a3)
#define SimTK_ASSERT4(cond, msg, a1, a2, a3, a4)   SimTK_ASSERT4_ALWAYS(cond,msg,a1,a2,a3,a4)


Define Documentation

#define SimTK_APIARGCHECK ( cond,
className,
methodName,
msg   )     SimTK_APIARGCHECK_ALWAYS(cond,className,methodName,msg)

#define SimTK_APIARGCHECK1 ( cond,
className,
methodName,
fmt,
a1   )     SimTK_APIARGCHECK1_ALWAYS(cond,className,methodName,fmt,a1)

#define SimTK_APIARGCHECK1_ALWAYS ( cond,
className,
methodName,
fmt,
a1   ) 

Value:

do{if(!(cond))SimTK_THROW4(SimTK::Exception::APIArgcheckFailed, \
                    (className),(methodName),(fmt),(a1));           \
    }while(false)

#define SimTK_APIARGCHECK2 ( cond,
className,
methodName,
fmt,
a1,
a2   )     SimTK_APIARGCHECK2_ALWAYS(cond,className,methodName,fmt,a1,a2)

#define SimTK_APIARGCHECK2_ALWAYS ( cond,
className,
methodName,
fmt,
a1,
a2   ) 

Value:

do{if(!(cond))SimTK_THROW5(SimTK::Exception::APIArgcheckFailed,         \
                    (className),(methodName),(fmt),(a1),(a2));              \
    }while(false)

#define SimTK_APIARGCHECK3 ( cond,
className,
methodName,
fmt,
a1,
a2,
a3   )     SimTK_APIARGCHECK3_ALWAYS(cond,className,methodName,fmt,a1,a2,a3)

#define SimTK_APIARGCHECK3_ALWAYS ( cond,
className,
methodName,
fmt,
a1,
a2,
a3   ) 

Value:

do{if(!(cond))SimTK_THROW6(SimTK::Exception::APIArgcheckFailed,         \
                    (className),(methodName),(fmt),(a1),(a2),(a3));         \
    }while(false)

#define SimTK_APIARGCHECK4 ( cond,
className,
methodName,
fmt,
a1,
a2,
a3,
a4   )     SimTK_APIARGCHECK4_ALWAYS(cond,className,methodName,fmt,a1,a2,a3,a4)

#define SimTK_APIARGCHECK4_ALWAYS ( cond,
className,
methodName,
fmt,
a1,
a2,
a3,
a4   ) 

Value:

do{if(!(cond))SimTK_THROW7(SimTK::Exception::APIArgcheckFailed,             \
                    (className),(methodName),(fmt),(a1),(a2),(a3),(a4));        \
    }while(false)

#define SimTK_APIARGCHECK5 ( cond,
className,
methodName,
fmt,
a1,
a2,
a3,
a4,
a5   )     SimTK_APIARGCHECK5_ALWAYS(cond,className,methodName,fmt,a1,a2,a3,a4,a5)

#define SimTK_APIARGCHECK5_ALWAYS ( cond,
className,
methodName,
fmt,
a1,
a2,
a3,
a4,
a5   ) 

Value:

do{if(!(cond))SimTK_THROW8(SimTK::Exception::APIArgcheckFailed,             \
                    (className),(methodName),(fmt),(a1),(a2),(a3),(a4),(a5));   \
    }while(false)

#define SimTK_APIARGCHECK_ALWAYS ( cond,
className,
methodName,
msg   ) 

Value:

do{if(!(cond))SimTK_THROW3(SimTK::Exception::APIArgcheckFailed, \
                    (className),(methodName),(msg));                \
    }while(false)

#define SimTK_ASSERT ( cond,
msg   )     SimTK_ASSERT_ALWAYS(cond,msg)

#define SimTK_ASSERT1 ( cond,
msg,
a1   )     SimTK_ASSERT1_ALWAYS(cond,msg,a1)

#define SimTK_ASSERT1_ALWAYS ( cond,
msg,
a1   )     do{if(!(cond))SimTK_THROW3(SimTK::Exception::Assert,#cond,(msg),(a1));}while(false)

#define SimTK_ASSERT2 ( cond,
msg,
a1,
a2   )     SimTK_ASSERT2_ALWAYS(cond,msg,a1,a2)

#define SimTK_ASSERT2_ALWAYS ( cond,
msg,
a1,
a2   )     do{if(!(cond))SimTK_THROW4(SimTK::Exception::Assert,#cond,(msg),(a1),(a2));}while(false)

#define SimTK_ASSERT3 ( cond,
msg,
a1,
a2,
a3   )     SimTK_ASSERT3_ALWAYS(cond,msg,a1,a2,a3)

#define SimTK_ASSERT3_ALWAYS ( cond,
msg,
a1,
a2,
a3   )     do{if(!(cond))SimTK_THROW5(SimTK::Exception::Assert,#cond,(msg),(a1),(a2),(a3));}while(false)

#define SimTK_ASSERT4 ( cond,
msg,
a1,
a2,
a3,
a4   )     SimTK_ASSERT4_ALWAYS(cond,msg,a1,a2,a3,a4)

#define SimTK_ASSERT4_ALWAYS ( cond,
msg,
a1,
a2,
a3,
a4   )     do{if(!(cond))SimTK_THROW6(SimTK::Exception::Assert,#cond,(msg),(a1),(a2),(a3),(a4));}while(false)

#define SimTK_ASSERT_ALWAYS ( cond,
msg   )     do{if(!(cond))SimTK_THROW2(SimTK::Exception::Assert,#cond,(msg));}while(false)

#define SimTK_INDEXCHECK ( lb,
ix,
ub,
where   )     SimTK_INDEXCHECK_ALWAYS(lb,ix,ub,where)

#define SimTK_INDEXCHECK_ALWAYS ( lb,
ix,
ub,
where   ) 

Value:

do{if(!((lb)<=(ix)&&(ix)<(ub)))SimTK_THROW5(SimTK::Exception::IndexOutOfRange,   \
                    #ix,(lb),(ix),(ub),(where));}while(false)

#define SimTK_SIZECHECK ( sz,
maxsz,
where   )     SimTK_SIZECHECK_ALWAYS(sz,maxsz,where)

#define SimTK_SIZECHECK_ALWAYS ( sz,
maxsz,
where   ) 

Value:

do{if(!(0<=(sz)&&(sz)<=(maxsz)))SimTK_THROW4(SimTK::Exception::SizeOutOfRange,   \
                    #sz,(sz),(maxsz),(where));}while(false)

#define SimTK_SIZECHECK_NONNEG ( sz,
where   )     SimTK_SIZECHECK_NONNEG_ALWAYS(sz,where)

#define SimTK_SIZECHECK_NONNEG_ALWAYS ( sz,
where   ) 

Value:

do{if((sz)<0)SimTK_THROW3(SimTK::Exception::SizeWasNegative,   \
                    #sz,(sz),(where));}while(false)

#define SimTK_STAGECHECK_EQ ( currentStage,
targetStage,
methodNm   )     SimTK_STAGECHECK_EQ_ALWAYS(currentStage,targetStage,methodNm)

#define SimTK_STAGECHECK_EQ_ALWAYS ( currentStage,
targetStage,
methodNm   ) 

Value:

do{if((currentStage)!=(targetStage)) SimTK_THROW3(SimTK::Exception::StageIsWrong,   \
        (currentStage),(targetStage),(methodNm));}while(false)

#define SimTK_STAGECHECK_GE ( currentStage,
targetStage,
methodNm   )     SimTK_STAGECHECK_GE_ALWAYS(currentStage,targetStage,methodNm)

#define SimTK_STAGECHECK_GE_ALWAYS ( currentStage,
targetStage,
methodNm   ) 

Value:

do{if(!((currentStage)>=(targetStage))) SimTK_THROW3(SimTK::Exception::StageTooLow,   \
        (currentStage),(targetStage),(methodNm));}while(false)

#define SimTK_STAGECHECK_LE ( currentStage,
targetStage,
methodNm   )     SimTK_STAGECHECK_LE_ALWAYS(currentStage,targetStage,methodNm)

#define SimTK_STAGECHECK_LT_ALWAYS ( currentStage,
targetStage,
methodNm   ) 

Value:

do{if((currentStage)>=(targetStage)) SimTK_THROW3(SimTK::Exception::StageTooHigh,   \
        (currentStage),(targetStage),(methodNm));}while(false)

#define SimTK_STAGECHECK_RANGE ( lower,
current,
upper,
methodNm   )     SimTK_STAGECHECK_RANGE_ALWAYS(lower,current,upper,methodNm)

#define SimTK_STAGECHECK_RANGE_ALWAYS ( lower,
current,
upper,
methodNm   ) 

Value:

do{if(!((lower)<=(current)&&(current)<=(upper))) SimTK_THROW4(SimTK::Exception::StageOutOfRange,   \
        (lower),(current),(upper),(methodNm));}while(false)

#define SimTK_STAGECHECK_TOPOLOGY_REALIZED ( cond,
objType,
objName,
methodName   )     SimTK_STAGECHECK_TOPOLOGY_REALIZED_ALWAYS(cond,objType,objName,methodName)

#define SimTK_STAGECHECK_TOPOLOGY_REALIZED_ALWAYS ( cond,
objType,
objName,
methodNm   ) 

Value:

do{if(!(cond)) SimTK_THROW3(SimTK::Exception::RealizeTopologyMustBeCalledFirst, \
        (objType),(objName),(methodNm));}while(false)

#define SimTK_VALUECHECK ( lb,
val,
ub,
valName,
where   )     SimTK_VALUECHECK_ALWAYS(lb,val,ub,valName,where)

#define SimTK_VALUECHECK_ALWAYS ( lb,
val,
ub,
valName,
where   ) 

Value:

do{if(!(lb)<=(val)&&(val)<=(ub)))SimTK_THROW5(SimTK::Exception::ValueOutOfRange,   \
                    (valName),(lb),(val),(ub),(where));}while(false)

#define SimTK_VALUECHECK_NONNEG ( val,
valName,
where   )     SimTK_VALUECHECK_NONNEG_ALWAYS(val,valName,where)

#define SimTK_VALUECHECK_NONNEG_ALWAYS ( val,
valName,
where   ) 

Value:

do{if((val)<0)SimTK_THROW3(SimTK::Exception::ValueWasNegative,   \
                    (valName),(val),(where));}while(false)


Generated on Thu Feb 28 01:34:34 2008 for SimTKcommon by  doxygen 1.4.7