I have get_massege function which needs to return 32 bit integer.
So i thought about using u32. Then i realized i have some ERROR CODEs
which need to be negative (to distinguish them from 32 bit value).
they are numerous: -1,-2,-3,-4,-5
so basically i need 33 bits integer :/
Instead of int getMessage(args); // returns a value or an error code
do
1 2 3
// Get the message. Returns 0 on success and a negative value on error.
// On success, set "result" to the integer result.
int getMessage(args, int &result);
I liked the above for a long time, but recently its been a neverending source of frustration.
I keep having to do this:
int unnecessary;
getMessage(arg, unnecessary);
if(unnecessary == value)
...
instead of
if(getMessage(arg) == value)
with at times 5 or so variables who only exist because of the reference parameter design.
When I do it new these days I will return a tuple or pair or something, anything, to avoid this aggravation. Is that just me?
It is frustrating because it introduces more verbiage; becomes even more frustrating when it sabotages using const proactively. As a minor irritant, it may also be slightly less efficient.
if( foo(something)->result ) //what to do if foo failed somehow?
every attempt to make that happen without bloat is a struggle.
about the smallest I have to offer generally is factoring it out if it makes sense:
if(!condition_that_makes_foo_fail && foo(something)->result)
{}
else
{throw/complain/whatever}
and where possible, handling it inside of foo() so that foo can't give a bad result that goes forward, which makes the straight up call safe again.
there are many, many other ways as well. Error handling is a chore, but we certainly have loads of ways to manage it.
int Get_Msg (int ch, int* result){
u8 IS_FIFO_Empty;
u32 fifo_stat;
u32 data;
if ((ch<0)||(ch>Rx_num-1))
return CH_PARAM_ERROR;
if (Rx_Channels[ch].IsReady == 0)
return IDLE_CHANNEL;
fifo_stat = Xil_In32(XPAR_AXI_BRAM_CTRL_0_S_AXI_BASEADDR+0X204+(0x10)*ch);
IS_FIFO_Empty = (fifo_stat>>24) & 0x1; // 1 if fifo is empty
if (IS_FIFO_Empty==0){
*result = Xil_In32(XPAR_AXI_BRAM_CTRL_0_S_AXI_BASEADDR+0X208 (0x10)*ch);
return SUCCESS;
}
elsereturn FIFO_EMPTY;
}
What i am doing is if i have any error the function return negative value, otherwise it returns 0 . in main i just check:
1 2 3 4 5 6 7
stat = Get_Msg (Channel,&result);
if (stat<0) {
xil_printf("Parameters error\n\r");
xil_printf("Status %d\n\r",stat);
break;
}
else data = result; // in this point i know i get viable result
error handing is both a concept and a tool in c++.
what you have above is conceptual error handling: you have an error, detect it, and handle it. This is fine.
c++ provides tools as well, which is the try/throw/catch keywords and syntax. you try to do some block of code, if there is a problem you throw an error, and after that you catch the error and handle it (else, if you do not, the program will crash with an unhandled exception code).
** the try/etc is more correctly called exception handling, if you want a better keyword to search on how to use them.
the exception handling tools are very powerful and flexible, and prone to temptation to abuse them. Beware using them as an alternative condition block, and keep them for real errors. They do not perform well as conditions or goto like constructs, and the code becomes difficult to understand what is an error and what is not.