Forums | developer.brewmp.com Forums | developer.brewmp.com

Developer

Forums

Forums:

For quite a long time I've been indulged in Brew development. As I have come across many times and in many situations where I have to put a lot of NULL checks, return-values of functions etc.. to make the code robust and foolproof. But it makes the code lengthy and ugly some times too. Also, the development efforts increases for such handlings.

I am sure that Brew developer community will be very happy if Qualcomm gives provision for a Global mechanism like "Try-Catch-Throw".

It would make Brew apps more robust and time-worthy.

Feedback awaited...
SoftEast

There's compiler support for exceptions already. Did you mean something else? You could always define a macro that throws an exception if a return code is not SUCCESS. You could call it, ooh, User::LeaveIfError :)

There's compiler support for exceptions already. Did you mean something else? You could always define a macro that throws an exception if a return code is not SUCCESS. You could call it, ooh, User::LeaveIfError :)

BenBlaukopf wrote:There's compiler support for exceptions already. Did you mean something else? You could always define a macro that throws an exception if a return code is not SUCCESS. You could call it, ooh, User::LeaveIfError :)
Could you please illustrate such compiler support with details..?

BenBlaukopf wrote:There's compiler support for exceptions already. Did you mean something else? You could always define a macro that throws an exception if a return code is not SUCCESS. You could call it, ooh, User::LeaveIfError :)
Could you please illustrate such compiler support with details..?

You can define a macro like this and use it anywhere you need to check the return code for SUCCESS like ISHELL_CreateInstance instead of pasting the same piece of this code everywhere#ifndef BREAKIF
#define BREAKIF(x) \
if (SUCCESS != x) \
{ \
break; \
}
#endif
Similary you can similar macro for NULL pointer check (like pointers returned by MALLOC or WSTRDUP)#ifndef BREAKIFNULL
#define BREAKIFNULL(p,nRetVal) if( NULL == (p))\
{nRetVal = ENOMEMORY;\
break;\
}
#endif
Similarly, you can have macros for Addref, Release.
In addition you can also put DBGPRINTF messages in these macros like
#ifndef BREAKIFNULL_FATAL
#define BREAKIFNULL_FATAL(ptr,str,nRetVal) if( NULL == (ptr))\
{ nRetVal = ENOMEMORY;\
DBGPRINTF_FATAL(str,nRetVal);\
break;\
}
#endif
Usage of these macros can make the code look good without any cluttering and unnecessary code for check at all places.
Examples usages1)
*ppDisplayStr=(AECHAR *)MALLOC(nStrSize);
BREAKIFNULL_FATAL(*ppDisplayStr,"Failed to MALLOC *ppDisplayStr: %d",nRetVal);
2)
nRetVal=IWIDGET_GetViewModel(pIWidget,&pIViewModel);
BREAKIF(nRetVal);
nRetVal=IVECTORMODEL_GetAt(pMe->pIMyVector,nIndex,(void**)&pData);
BREAKIF(nRetVal);
3)
pIPrevForm=IROOTFORM_GetForm(pRootForm,pMe->pIForm,FALSE,FALSE);
BREAKIFNULL(pIPrevForm,nRetVal);

You can define a macro like this and use it anywhere you need to check the return code for SUCCESS like ISHELL_CreateInstance instead of pasting the same piece of this code everywhere#ifndef BREAKIF
#define BREAKIF(x) \
if (SUCCESS != x) \
{ \
break; \
}
#endif
Similary you can similar macro for NULL pointer check (like pointers returned by MALLOC or WSTRDUP)#ifndef BREAKIFNULL
#define BREAKIFNULL(p,nRetVal) if( NULL == (p))\
{nRetVal = ENOMEMORY;\
break;\
}
#endif
Similarly, you can have macros for Addref, Release.
In addition you can also put DBGPRINTF messages in these macros like
#ifndef BREAKIFNULL_FATAL
#define BREAKIFNULL_FATAL(ptr,str,nRetVal) if( NULL == (ptr))\
{ nRetVal = ENOMEMORY;\
DBGPRINTF_FATAL(str,nRetVal);\
break;\
}
#endif
Usage of these macros can make the code look good without any cluttering and unnecessary code for check at all places.
Examples usages1)
*ppDisplayStr=(AECHAR *)MALLOC(nStrSize);
BREAKIFNULL_FATAL(*ppDisplayStr,"Failed to MALLOC *ppDisplayStr: %d",nRetVal);
2)
nRetVal=IWIDGET_GetViewModel(pIWidget,&pIViewModel);
BREAKIF(nRetVal);
nRetVal=IVECTORMODEL_GetAt(pMe->pIMyVector,nIndex,(void**)&pData);
BREAKIF(nRetVal);
3)
pIPrevForm=IROOTFORM_GetForm(pRootForm,pMe->pIForm,FALSE,FALSE);
BREAKIFNULL(pIPrevForm,nRetVal);

Softeast wrote:Could you please illustrate such compiler support with details..?
RVCT 3.0 onwards have exception support.

Softeast wrote:Could you please illustrate such compiler support with details..?
RVCT 3.0 onwards have exception support.

Also if "break" thingy will not do the work to jump out, you can use goto
Then you can do:
#define EQUALSZEROG2(exp, lbl) if( (exp) == 0) goto lbl
static boolean some(xxxx){
.....
x1 = ISHELL_some1(..);
EQUALSZEROG2(x1, CRAZYTHING);
......
CRAZYTHING:
// Handle deallocations, free, etc...
DBGPRINTF("Handling not sane values");
return FALSE;

even some like:
#define EQUALSG2(exp1, exp2, lbl) if( (exp1) == (exp2)) goto lbl
static boolean some(xxxx){
.....
x1 = ISHELL_some1(..);
EQUALSG2(x1, !SUCESS, CRAZYTHING);
......
CRAZYTHING:
// Handle deallocations, free, etc...
DBGPRINTF("Handling not sane values");
return FALSE;

Also you can still use normal way of code, but without code much...
#define ISSUCCESS(exp1) if( (exp1) == SUCCESS)
#define ISNOTSUCCESS(exp1) if( (exp1) != SUCCESS)
static boolean some(xxxx){
.....
ISSUCCESS(x1 = ISHELL_some1(..)){
ISNOTSUCCESS( x2 = ISHELL_somex(...) ){
DBGPRINTF("Quiting function");
return FALSE;
}
DBGPRINTF("Doing work, because x1 is required to ve valid and x2 as a sane value");
IDISPLAY_x(x1);
some(x2);
// done, liberate x1 and x2
return TRUE;
}
return FALSE;

Also if "break" thingy will not do the work to jump out, you can use goto
Then you can do:
#define EQUALSZEROG2(exp, lbl) if( (exp) == 0) goto lbl
static boolean some(xxxx){
.....
x1 = ISHELL_some1(..);
EQUALSZEROG2(x1, CRAZYTHING);
......
CRAZYTHING:
// Handle deallocations, free, etc...
DBGPRINTF("Handling not sane values");
return FALSE;

even some like:
#define EQUALSG2(exp1, exp2, lbl) if( (exp1) == (exp2)) goto lbl
static boolean some(xxxx){
.....
x1 = ISHELL_some1(..);
EQUALSG2(x1, !SUCESS, CRAZYTHING);
......
CRAZYTHING:
// Handle deallocations, free, etc...
DBGPRINTF("Handling not sane values");
return FALSE;

Also you can still use normal way of code, but without code much...
#define ISSUCCESS(exp1) if( (exp1) == SUCCESS)
#define ISNOTSUCCESS(exp1) if( (exp1) != SUCCESS)
static boolean some(xxxx){
.....
ISSUCCESS(x1 = ISHELL_some1(..)){
ISNOTSUCCESS( x2 = ISHELL_somex(...) ){
DBGPRINTF("Quiting function");
return FALSE;
}
DBGPRINTF("Doing work, because x1 is required to ve valid and x2 as a sane value");
IDISPLAY_x(x1);
some(x2);
// done, liberate x1 and x2
return TRUE;
}
return FALSE;