Returning void from a double function? - c

I have a function which is a double and normally returns the new value for a variable, but sometimes I don't want to change the variable and I would like to signal that by returning a special value, for example void. Is that possible?
For example:
double GetNewValue(int feature) {
switch( feature ) {
case TYPE1:
return void; // or maybe use return; here?
case TYPE2:
return 2.343;
default:
return featureDefaultValue;
}
}
PS: I know I can use NaN, but I already use it as a valid value with another meaning (not yet a number is available).
/EDIT: Thank you all for your answers, these 3 answers are all applicable to my problem and are all equally valid. I struggle right now in choosing which one I'm going to use (which will be the one I will accept, but I wish I could accept them all!).

In this case, you need to return two things from a function, not one. A common way to do so is taking a pointer to the return value, and returning a yes/no flag to indicate the validity of the actual double:
int GetNewValue(double *res, int feature) {
switch( feature ) {
case TYPE1:
return 0; // no change to res
case TYPE2:
*res = 2.343;
return 1;
default:
*res = featureDefaultValue;
return 1;
}
Now instead of doing this
double res = GetNewValue(myFeature);
the users of your function would need to do this:
double res;
if (GetNewValue(&res, myFeature)) {
// use res here - it's valid
} else {
// do not use res here - it's not been set
}

One way to do this is to pass the result variable as a pointer:
void AssignNewValue(int feature, double* result)
{
switch( feature ) {
case TYPE1:
return;
case TYPE2:
*result = 2.343;
break;
default:
*result = featureDefaultValue;
break;
}
}
Used like:
double featureValue = 42.0;
/* ... */
AssignNewValue(feature, &featureValue);

It sounds like you want an "optional" return parameter. You don't seem to (and rightly so) want to use 0.0 as the "no value" result because that means 0.0 can't be used for an actual value.
2 good solutions you sometimes see for this is to either use a "result code", or to use a pointer as the return result. (Pointers are more complicated). I'll start with #1 first:
1. Result codes
// definitions for result codes
#define FAIL 0
#define OK 1
int GetNewValue(int feature, double *result) {
switch( feature ) {
case TYPE1:
*result = 0.0 ;
return FAIL ; // caller of the function should recognize
// the call "failed"
case TYPE2:
*result = 200.0 ;
return OK ;
default:
*result = 47.0 ;
return OK;
}
}
// use:
double feature ;
int result = GetNewValue( 5, &feature ) ;
if( result == OK )
{
// do something with "feature"
}
2. Using pointers
double* GetNewValue(int feature) {
switch( feature ) {
case TYPE1:
return NULL ; // NO POINTER means FAIL
case TYPE2:
return new double(200) ;
default:
return new double( 47 ) ;
}
}
// use:
double* result = GetNewValue( 5 ) ;
if( result != NULL )
{
// result had a value, so you can use it
}
The gotcha with pointers is you need to remember to delete the result
delete result ; // when done with pointer that was created
// with `new`, you must `delete` it after
// otherwise you'll get a memory leak

Related

How to return an error from a returning value function in C language [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I am wondering for a while what is the best practice to handle errors in returning values function in C.
First, I would like to introduce the need then share a few solutions that I tried and to hear different ideas.
The issue is when I have a returning value function, this function can return any value in the range, and the function sometimes has a problem that it must return as well to the calling function, it cannot use the traditional return for that cause.
How can I handle that error in the calling function?
few notes:
1. I am an Embedded programer, and I am keen on keeping my function reentrant (pure) functions in a way that different interrupts won't harm the globals, I hardly use globals in my code.
I can't handle it with 0 or -1 because it is a valid return as well.
the errno solution doesn't support pure functions as well as 1.
4.I tried using structs of return which I have one field for the value and one field for the error if it has occurred.
unsigned int squre(unsigned int num)
{
return num*num;
}
programmer say I would like to have handle for overflow.
struct returnUnsignedint squre(unsigned int num)
{
struct returnUnsignedint returnValue;
if (num>65535) { //my embedded system over flow
returnValue.error = 1;
}
returnValue.value = num*num;
return returnValue;
}
is there a better option out there?
Let me know if you have different point of view, or solutions.
I would appreciate any help, thanks!
There's no "one size fits all" solution, since it depends on needs of your program.
However, there are a few possibilities.
One way is to specify that one possible return value of your function can indicate an error occurred. For example, since not every value of an unsigned is the square of another, pick a suitable value and return that.
unsigned sqre(unsigned x)
{
if (x == 0U)
{
return 0U;
}
else if (UINT_MAX/x >= x) /* use fact that UINT_MAX is typically not a perfect square */
{
return x*x;
}
else
{
return UINT_MAX;
}
}
(Note, in the above, that I have eliminated your implicit assumption that unsigned is at least 32-bit, by avoiding use of the magic value 65535).
Another option is to do what some standard library functions do: return 0 (or, in the case of unsigned, return 0U, on error) even if it is feasible that value is valid. That means your function always returns a usable value, but the caller will need to decide what to do if your function returns zero.
Another option is to return a data structure
struct Return
{
unsigned value;
int error;
};
struct Return sqre(unsigned x)
{
struct Return retval;
retval.error = 0;
if (x == 0)
{
retval.value = 0U;
}
else if (UINT_MAX/x >= x) /* use fact that UINT_MAX is typically not a perfect square */
{
retval.value = x*x;
}
else
{
retval.error = 1;
}
return retval;
}
The trade-off is that forces the caller to create an instance of the struct and then check or extract data from it.
Another is to provide a second argument that provides an error indication.
unsigned sqre(unsigned x, int *error)
{
*error = 0;
if (x == 0U)
{
return 0U;
}
else if (UINT_MAX/x >= x) /* use fact that UINT_MAX is typically not a perfect square */
{
return x*x;
}
else
{
*error = 1;
return 0U; /* falling off end without a return statement gives undefined behaviour */
}
}
The disadvantage of the above is that the caller can forget to check the error condition. It is trivial to modify the above so it checks if error is NULL and then doesn't modify *error (and then allow the caller to specify a NULL to indicate no interest in the error condition).
An alternative is for the function to return the error condition, and require the caller to pass the address of a variable to hold the result (if no error occurs). A disadvantage of this is that the result from the function can't be used directly in larger expressions.
Since, technically, overflow of unsigned gives well-defined behaviour (essentially modulo arithmetic), use your version that does no checks. This option isn't feasible if the function returns a signed int (since overflow gives undefined behaviour). This requires the caller to deal with the fact that the returned value may be truncated (e.g. high order part of the value lost).
Yet another option is for the function to terminate with prejudice if an overflow would occur. For example;
unsigned sqre(unsigned x)
{
assert(x == 0 || UINT_MAX/x < x); /* from <assert.h> */
return x*x;
}
This removes the responsibility of the caller to check. However, the caller (if program termination is undesirable) must then ensure the argument passed is valid. Alternatively, the end-user would need to be willing to accept that the program may terminate on bad data.
Another option is to return the error code and write the output value to a parameter:
int sqr( unsigned int num, unsigned int *result )
{
if ( num > 65535 )
return 0;
*result = num * num;
return 1;
}
This isn’t always the most convenient option (especially if you want to use sqr as part of a larger arithmetic expression), but it should meet your requirements.
EDIT
Of course, you could always go the other way - return the value and write the error code to a parameter:
unsigned int sqr( unsigned int num, int *err ) { ... }
but frankly I prefer the first version, since you aren't tempted to use the return value unless you know the operation succeeded.
Following up John's answer I propose an additional macro to be able to use the function in a "larger arithmetic expressions"
#include <stdlib.h> /* for EXIT_xxx macros */
#include <stdio.h> /* for perror() */
#include <errno.h> /* for errno */
int sqr(unsigned int num, unsigned int *psqr)
{
int result = 0;
if (NULL == psqr)
{
result = -1;
errno = EINVAL;
}
else if (num > 0xffffU)
{
result = -1;
errno = ERANGE;
}
else
{
*psqr = num * num;
}
return result;
}
#define SQR(x, y) \
((-1 == sqr(x, &y)) \
? (perror("sqr() failed"), exit(EXIT_FAILURE), 0U) \
: y \
)
Some tests below (please note that the macro SQR() has to end the program if sqr() fails):
int main(void)
{
unsigned int r, i;
puts("Test case 1:");
i = 42;
if (-1 == sqr(i, &r))
{
perror("sqr() failed");
}
else
{
printf("sqr(%u) = %u\n", i, r);
}
puts("Test case 2:");
i = 0x10000;
if (-1 == sqr(i, &r))
{
perror("sqr() failed");
}
else
{
printf("sqr(%u) = %u\n", i, r);
}
puts("Test case 3:");
if (-1 == sqr(i, NULL))
{
perror("sqr() failed");
}
else
{
printf("sqr(%u) = %u\n", i, r);
}
puts("Test case 4:");
r = SQR(1, r) + SQR(2, r);
printf("sqr(%u) + sqr(%u) = %u\n", 1, 2, r);
puts("Test case 5:");
r = SQR(0x10000, r) + SQR(2, r);
printf("sqr(%u) + sqr(%u) = %u\n", 0x10000, 2, r);
puts("Test case 6:");
r = SQR(NULL, r) + SQR(2, r);
printf("sqr(%u) + sqr(%u) = %u\n", 0x10000, 2, r);
return EXIT_SUCCESS;
}
The output is:
Test case 1:
sqr(42) = 1764
Test case 2:
sqr() failed: Numerical result out of range
Test case 3:
sqr() failed: Invalid argument
Test case 4:
sqr(1) + sqr(2) = 5
Test case 5:
sqr() failed: Numerical result out of range
Test case 6 is never reached as test case 5 ends the program.

parsing with recursion - brackets

Could some give me a hint at this problem :
An expression is correct only if it contains parentheses and braces properly closed and no other character, even space. For example, () ({} () ({})) is a correct expression, whereas ({)} is not a correct expression or {} ({})). An empty expression (which does not contain any character) is correct.
Given a string expression determine if the expressions is correct and if is determine the maximum level of nesting. Maximum level of nesting parentheses is the maximum number of one another.
Examples
{}({}){{(({}))}}
answer : 5
{}({})) -1 (because the expression is incorrect)
That's what I've did so far.
#include <stdio.h>
#include <stdlib.h>
FILE *fi, *fo;
int first, er;
void X();
void Y();
void S() {
X();
Y();
}
void X() {
if(first=='{') {
first=fgetc(fi);
X();
if(first=='}')
first=fgetc(fi);
else
er=1;
S();
}
}
void Y() {
if(first=='(') {
first=fgetc(fi);
Y();
if(first==')')
first=fgetc(fi);
else
er=1;
S();
}
}
int main()
{
fi = fopen("brackets.in","r");
fo = fopen("brackets.out","w");
first=fgetc(fi);
S();
if(first!='\n')
er=-1;
fprintf(fo,"%d",er);
fclose(fi);
fclose(fo);
return 0;
}
First off, it helps to think of your problem as a formal grammar.
S = The Language you are testing for
S->
NUL // Empty
SS // S followed by itself.
[ S ] // Case 1
( S ) // Case 2
{ S } // Case 3
Since this grammar only has one symbol (S), you only need one parsing method.
The following code is incomplete but hopefully it gets the idea across.
char curr_char;
int main (void)
{
curr_char = getc();
result = parse_s();
return 0;
}
// Parse the S pattern off input. When this method completes, curr_char points to the character AFTER S.
// Returns recursion count or -1 on fail.
int parse_s()
{
max_count = 0;
while(true)
{
int curr_count = 0;
switch 'curr_char':
{
case '[': // [
int count = parse_s(); // S
if (count == -1) return -1; // The S must be valid
if (curr_char != ']') return -1; // ]
curr_char = getc(); // Advance past the ]
curr_count = count + 1; // This expression is 1 nest greater than its contained S
break;
case '(':
// XXX
break;
case '{':
// XXX
break;
default:
// This is either the SS (find the max of the two), the NUL case (return 0), or an error (return -1)
break;
}
// In the SS case you're gonna have to loop and do something here.
}
return max_count;
}

Creating int function which in case of an error can not return a valid int value

I am trying to create a function will return the value located in the struct. My issue is trying to figure out what I can return by the function if theInfo = NULL?
Below is what I have created so far. Is this possible to do?
int getTime(struct * theInfo){
if(theInfo != NULL){
return theInfo->waitTime;
}
else{
printf("getTime Patron is nonexistent\n");
return(thePatron);
}
}
You need to return two pieces of information - the number, and an indication of whether or not that number is valid. One way to do it is changing the signature of the function to indicate whether or not it returned anything, and in case when it does, stick that value in a variable. Here is an example of how you can do it:
// This function returns 1 or 0.
// 1 indicates success; 0 indicates failure
// If your compiler is up to C99 standard, use "bool" instead of "int" below
int getTime(struct * theInfo, int *result) {
if(theInfo != NULL){
*result = theInfo->waitTime;
return 1;
} else{
// result stays unchanged
return 0;
}
}
Now you can use this new function like this:
int res;
if (getTime(&myInfo, &res)) {
printf("getTime returned %d\n", res);
} else {
printf("getTime Patron is nonexistent\n");
}
A less general alternative can be used when you do not need to return a full range of numbers. For example, if the valid time returned by your function is always positive, you could adopt a convention that uses negative numbers to indicate that there was an error. This approach is also valid, but it relies more on a convention, so a reader of your code would need to look through your function documentation to see what is going on.
You could pass a pointer and return a boolean value indicating success:
bool getTime(MyStruct* info, int* time) {
if (info) {
*time = info->waitTime;
return true;
}
*time = 0;
return false;
}
Then somewhere you would just call:
int time;
if (!getTime(info, &time)) {
// TODO: retrieval of time failed
}
Just return -1. I am sure that wait time is always positive.
So return -1 if it is NULL and then check for -1
else{
printf("getTime Patron is nonexistent\n");
return -1;
}
void someFunc() {
//...
int wtime = getTime(astruct);
if (wtime == -1)
// error
//...
}

Switch Statement in C

I have the following if-statements:
if (strcmp(registerName, "zero"))
return 00000;
else if (strcmp(registerName, "at"))
return 00001;
else if (strcmp(registerName, "v0"))
return 00010;
else if (strcmp(registerName, "v1"))
return 00011;
It's actually really long - about 20 if-statements. Therefore, I would like to use a switch. How would I convert that to switch when each statement has a different condition?
I tried something as the code below, but it does not work:
int registerAddress;
switch(registerAddress) {
case 1 (strcmp(registerName, "zero")):
regsiterAddress = 00000;
break;
case 2 (strcmp(registerName, "at")):
registerAddress = 00001;
break;
}
You can't — switch statements in C only work on primitive types, not on strings. You could use, say, a hash table or a search tree to optimize the matching, but for only 20 options that may not be worth the trouble.
What you could do, to clean up the code, is set up a mapping table:
struct str2Num {
char *str;
int num;
};
const struct str2Num registerMap[] = {
{ "zero", 00000 },
{ "at", 00001 },
{ "v0", 00010 },
{ "v1", 00011 },
{ NULL, 0 } /* end marker */
};
and do your matching like this:
int i;
for (i = 0; registerMap[i].str != NULL; i++) {
if (strcmp(registerName, registerMap[i].str) == 0) {
return registerMap[i].num;
}
}
/* handle no-match case here */
In fact, if you sorted the table alphabetically, you could even use bsearch() for fast matching.
You can only switch on integers, so this will not work.
If all you're doing is converting a string to an int, store the info in an array and look through it.
struct {
const char *name;
int value;
} fooMapping[] = {
{"zero",0},
{"at",1}
....
};
int foo2value(const char *name)
{
size_t i;
for(i = 0; i < sizeof fooMapping/sizeof fooMapping[0]; i++) {
if(strcmp(name, fooMapping[i].name) == 0)
return fooMapping[i].value;
}
return -1;
}
In a switch,
switch(number) {
case 1;
case 2;
case 7;
}
you are basically saying, if number = 1, then case 1. If number = 7, case 7. So what you need to do is assign each text value, in your case "zero""at""v0" and "v1", you would need to put these into an array, and in the switch statement, instead of switch(number) you would switch an integer that would correspond with the index number of whichever text you had. So if array[3] was = "v0", you would assign an integer to the index number (3) and then switch(integer). Hope this helped.
Why not use the ? operator like so:
return
strcmp(registerName, "zero")? 00000:
strcmp(registerName, "at") ? 00001:
strcmp(registerName, "v0") ? 00010:
strcmp(registerName, "v1") ? 00011:
...
Since switch-case only works with numbers or single chars, I would use a tool like GNU's gperf to create a perfect hash and switch on that value (followed by a strcmp() to be certain of an exact match). That ought to give you the desired performance improvement.

Arithmetical operations in certain script language

I am working on certain script language. Values containing structure is
struct myvar
{
char name[NAMELEN];
int type;
void* value;
}
type = 0 --> int* value
type = 1 --> char* value
type = 2 --> float* value
I faced some problem with arithmetic operations. It seems that I need to commit all sorts of type conversions over every single operation, that develops into writing a whole bunch of code for each of them, as in:
case 0: // "="
if(factor1.name)
{
if((factor1.type == 1) && (factor2.type==1))
{
free(factor1.value);
int len = (strlen((STRING)factor2.value)+1)*sizeof(char);
factor1.value = malloc(len);
memcpy(factor1.value,factor2.value,len);
}
else if((factor1.type == 2) && (factor2.type==2))
*(FLOAT*)factor1.value = *(FLOAT*)factor2.value;
else if((factor1.type == 0) && (factor2.type==0))
*(INTEGER*)factor1.value = *(INTEGER*)factor2.value;
else if((factor1.type == 0) && (factor2.type==2))
*(INTEGER*)factor1.value = *(FLOAT*)factor2.value;
else if((factor1.type == 2) && (factor2.type==0))
*(FLOAT*)factor1.value = *(INTEGER*)factor2.value;
else
GetNextWord("error");
}
break;
Is there some way to avoid this tiresome procedure? Otherwise I have no choice but to copy-paste this piece of code for each of "=","~","+","-","*","/","%",">","<",">=","<=","==","~=","AND","OR"
Use a union instead of a struct for the values:
struct myvar {
enum {
STRING, INT, FLOAT,
} type;
union {
char strval[NAMELEN];
int intval;
float fltval;
} val;
};
and then in executing the assignment operator in your scripting language you just do:
factor1 = factor2;
To fetch the right value based on the type you would do:
switch (operand.type) {
case STRING:
printf("%s", operand.val.strval);
break;
case INT:
printf("%d", operand.val.intval);
break;
case FLOAT:
printf("%f", operand.val.fltval);
break;
}
What about writing 3 toType functions:
char* toType0(myvar* from)
{
if (from->type == 0) return (char*)(from->value);
else if (from->type == 1) return itoa((int*)from->value);
else...
}
int toType1(myvar* from)
{
//convert to int...
}
Then in your conversion routines you can do:
switch (factor1.type)
{
case 0:
{ char* other = toType0(&factor2);
//assign or add or whatever....
};
break;
case 1:
{ int other = toType1(&factor2);
//assign or add or whatever....
};
break;
...
}
I would propose the following: when applying an operation, you should first coerce the operand types. E.g., if your operand types are int and float, you should coerce int value to a float one, and continue with the float version of the operation. The coercion is the same (or almost the same) for all the operations. With such an approach, you have much less cases to consider.

Resources