Can a function return two values? [duplicate] - c

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
returning multiple values from a function
I have a function which has to return two values
return(&ptr->keys[pos].value)
return Duplicate;
Here &ptr->keys[pos].value will give the address and Duplicate is a enum value set to 2... How to return these two values to another function, insert_front which is a linked list this &ptr->keys[pos].value is used as the first address for linked list.
What should be the prototype of the calling function I should write?

You can't return two values. However, you can return a single value that is a struct that contains two values.

You can return only one thing from a function. Either you make a struct which contains all the things you want to return, or you pass some function parameters by reference.

Robert's code is correct. However, you /can/ also use a struct without malloc, like so:
struct retstruct {
int a;
int b;
};
struct retstruct myfunc(void) {
struct retstruct r;
r.a = 1;
r.b = 2;
return r;
}
int main()
{
struct retstruct r;
r = myfunc();
printf("a=%d b=%d\n", r.a, r.b);
}
This is typically shunned because it's generally a bit more costly (performance-wise) to be passing around structs like this, but if you only need a couple values like this, it can be sufficient.

To return two values, you'll have to define some sort of struct to hold both values, and return an instance of that struct. Alternatively, you can pass an address or two to the function, and have it write the value(s) there.

No, you can not have two returns in a function, the first return will exit the function you will need to create an object. Note: I have not coded in C in a long time, so the syntax here is probably off.
public class link{
private int& ptr;
private int Duplicate;
public constructor link() {}
public setPtr(int& ptr) {
this->&ptr = ptr;
}
//set duplicate function
//get ptr function
//get duplicate function
}
and in the function you snippet you posted before create a link object set the values desired, and then return(link object);

In C/C++, a function cannot return two values. However, most often, this limitation actually makes sense: in any complex function, you want to update some data (a bunch of variables, an array, etc.), and return the status of the function, i.e., whether it was successful or not. As a result, a good practice is to return the status of the function, and use references (in C++) or pointers (in C) to modify your arguments, just like in this example in C:
int swap(int* a, int* b)
{
int tmp = *a;
*a = *b;
*b = tmp;
return 0;
}
Of course, this function is too simple to fail (sort of), but you get the idea :P
And then, if you really want your function to return 2 values, then you can use all the tricks proposed by the other answerers.

Like this:
typedef ret {
int val1;
int *val2;
} ret_t ;
// make sure to remember to free the struct when you're done with it
ret_t *myFunc( void ) {
ret_t *r = malloc( sizeof(ret_t) );
r->val1 = 1;
r->val2 = &r.val1;
return r;
}
// You can also return a copy of the struct on the stack
ret_t myFunc( void ) {
ret_t r;
r.val1 = 1;
r.val2 = &r.val1;
return r;
}

Related

Return a pointer to this new structure in the b parameter?

I'm trying to implement a void initBook(char *t, int y, BookType **b) function that dynamically allocates a new BookType structure, initializes the new structure’s fields to the values found in the t and y parameters, and returns a pointer to this new structure in the b parameter. I'm confused as to how I would do the last part where I have to return a pointer and would appreciate some help. I also thought I couldn't return values if a function is void? When I try compiling, I get the warning
'return' with a value, in function returning void.
Unrelated, but I also get the error
'*b' is a pointer; did you mean to use '->'? for the line *b->year = y;
which confuses me because I literally wrote an arrow. Does anyone know why I'm still getting this error?
Book.c
void initBook(char *t, int y, BookType **b){
*b = malloc(sizeof(BookType));
strcpy((*b)->title, t);
*b->year = y;
return b;
}
defs.h
typedef struct{
int id;
char *title;
int year;
} BookType;
You have two choices:
You simply set the values for *b as you are doing, and return nothing,
void initBook(char *t, int y, BookType **b) {
/* Assume BookType was malloc'ed outside of this function. */
(*b)->title = malloc(strlen(t) + 1);
strcpy((*b)->title, t);
(*b)->year = y;
return;
}
Don't pass b as an argument, but declare the function to return a pointer to it:
BookType* initBook(char *t, int y) {
BookType *b = malloc(sizeof(BookType));
b->title = malloc(strlen(t) + 1);
strcpy(b->title, t);
b->year = y;
return b;
}
A few comments on the above. In the first form, you could malloc if you want, but usually with that approach, it is assumed the malloc is done outside of the function (so you will remember to do the free there as well).
Also, in the first form, C convention is to put the returning arguments to the left, similar to assignment.
The second form is more like a "factory". The function mallocs and initializes the object (though the code does not set a value for id). But you will still need to free the pointer when you are done.
I've added a malloc for the title variable (per comment by Martin James that it is uninitialized). However, I would recommend that the title variable in the struct definition rather have some fixed maximum length (unless for your application that is not possible, that you really must allow it to be any length, in which case you will have to remember to free it later).

Store different Function return types in one union in C

I am having troubles formulating my objective in words so I am not too sure on how to express this.
Say I have two functions with the following signatures:
myBigStruct_t function1()
int function2()
with a definition of myBigStruct_t (that stores a lot of data and is somewhere else) and a union definition that can support the size of both return types:
typedef union myUnion{
myBigStruct_t A;
int B;
} myData_t;
union my2ndUnion{
myData_t data_;
char myArray[sizeOf(myData_t)];
} un2;
Can I do the following:
un2.myArray = function1();
...
if( something ){
myExpress = un2.data_.A;
else{
myOtherExpress = un2.data_.B;
}
...
un2.myArray = function2();
if( something ){
myExpress = un2.data_.A;
else{
myOtherExpress = un2.data_.B;
}
I know array data is normally passed by reference but most C compilers have a means of passing large data types that at least appear to be by value (regardless of whether or not a secret pointer is used).
I know its a bit contrived; I am just trying to get my ahead around unions.
Yes, that is exactly what unions do. I think that answers your question (let me know if it doesn't), but I'll give some more background.
If myBigStruct_t is defined like this:
typedef struct {
char someChars[256];
int someInts[512];
} myBigStruct_t;
Then when you do the assignment from function1(), the data is copied. There is no secret pointer involved.
On the other hand, if myBigStruct_t is defined like this:
typedef struct {
char *someChars; //This gets malloc'd in function1
int *someInts; //This gets malloc'd in function1
} myBigStruct_t;
Then the data is passed by reference, i.e. the data was not copied.
Note that your code as-is won't work because of the type mismatch between the return values of function1 and myArray, and the same for function2. You'll have to assign the specific union members:
un2.myArray.data_.A = function1();
un2.myArray.data_.B = function2();
I don't think there's any reason not to do it this way.
Edit (in response to your comment):
Why not just pass the array as a parameter instead of return value? A function prototype would be like: void foo(void* buffer, size_t buffer_len). I assume you fully understand pointers (otherwise function pointers are probably not the right way to solve your problem). A complete program might look like:
//All the functions use this prototype, although it isn't strictly necessary (your loop would just have to be smarter)
typedef void(*GenericFunctionCall)(void* buffer, size_t buffer_len);
//A struct with only a few bytes
typedef struct SmallStruct_s{
char value;
} SmallStruct_t;
//A struct with more bytes
typedef struct BigStruct_s {
char value[1024];
} BigStruct_t;
//Defining this makes it easy to get the maximum size of all the structs
typedef union AllStructs_s {
SmallStruct_t small;
BigStruct_t big;
} AllStructs_t;
//This function takes the buffer, casts it to a SmallStruct_t, and then does something with it (presumably sets param->value to something)
void smallFunction(void* buffer, size_t buffer_len) {
SmallStruct_t * param = (SmallStruct_t*)buffer;
//do something with param
}
//This function does the same with BigStruct_t
void bigFunction(void* buffer, size_t buffer_len) {
BigStruct_t * param = (BigStruct_t*)buffer;
//do something with param
}
int main() {
//This allocates memory for all the values generated by smallFunction and bigFunction.
AllStructs_t param;
//This is your table of function pointers
GenericFunctionCall functions[2];
functions[0] = smallFunction;
functions[1] = bigFunction;
//Loop through the functions and do something with the results
for (uint32_t function_index = 0; function_index < 2; ++function_index) {
functions[function_index]((void*)&param, sizeof(AllStructs_t));
//Do something with param here
}
}
Second edit:
Okay I now see what you're trying to do. You can't use union between to accept an arbitrary value, in this case unions are no different from any other data type (i.e. I can't assign BigStruct_t = SmallStruct_t).
Here's why: when the compiler generates code to handle the return value of a function, it is using the caller's memory to store the value. Because of that, you're not allowed to get a pointer to the return value for a function. In compiler-speak: the return value of a function is not an lvalue. The options for solving this are:
Store the return type of the function in the table, and use that assign the appropriate variable
Write a wrapper function for each function from the table, and have it convert the return type from return value to pointer parameter. Call the wrapper instead of the original function
Refactor the code completely

C qsort compare with non-global lookup table

I'm trying to refactor a utility that is currently a stand-alone C program, such that I can make a reusable library. It includes a sorting step of an array, according to the corresponding value within a global array.
// Global lookup table
double *rating;
// Comparator using lookup
int comp_by_rating(const void *a, const void *b) {
int * x = (int *) a;
int * y = (int *) b;
if (rating[*x] > rating[*y])
return 1;
else if (rating[*x] < rating[*y])
return -1;
else
return 0;
}
int main() {
int* myarray;
// ...
// initialize values of local myarray and global rating
// ...
qsort(myarray, length_myarray, sizeof(int), comp_by_rating);
// ...
return 0;
}
Is there a way for me to avoid having the rating lookup table global? I'm traditionally a C++ person so my first thought was a functor, but I have to stay in C and so I guess I'm functor-less. I also can't replace int *myarray with an array of structs holding the rating for each item, since other code requires the array in its current form. Do I have any other options?
I also can't replace int *myarray with an array of structs holding the rating for each item, since other code requires the array in its current form.
You can make a temporary replacement for sorting, call qsort, and harvest the results back into the original array:
struct rated_int {
int n;
double r;
};
struct rated_int *tmp = malloc(length_myarray * sizeof(struct rated_int));
for (int i = 0 ; i != length_myarray ; i++) {
tmp[i].n = myarray[i];
tmp[i].r = ratings[myarray[i]];
}
qsort(tmp, length_myarray, sizeof(struct rated_int), comp_struct);
for (int i = 0 ; i != length_myarray ; i++) {
myarray[i] = tmp[i].n;
}
free(tmp);
This way the rest of the code would see myarray as an array of integers.
That's how you roll in C. If you are worried about thread-safety, consider making the variable thread-local, so multiple threads have different copies of it:
static _Thread_local double *rating;
This is not supported by old compilers though, instead you need some sort of portability kludge. If you don't like this either, you can't really get around writing your own sorting routine that allows an extra parameter.
gcc provides nested functions as an extension to solve this problem, but they have other problems, namely, they require an executable stack which reduces the resilience of your program against bugs.
No, the array rating does not have to be global: You can use static here:
int comp_by_rating(const void *a, const void *b) {
static double *rating = { .. init here .. };
Alternate way to initialize it if members are non-constant:
int comp_by_rating(const void *a, const void *b) {
static double *rating = NULL;
if (!rating) {
// Initialize rating here
}
}

c function chaining possible?

I was wondering if it is possible in C (89/90) to chain function calls, and where it is defined in the C spec. I assume this isn't possible since a google search reveals no mention of it.
I thought of this because of a related conversation with a friend of mine where he told me that given a function returning a struct, you cannot perform any operations on said struct within the same statement; instead, you have to assign the result of the function to a variable, and then manipulate the struct via the variable instead of directly from the function result itself. This leads me to believe that you can't chain functions either, but I can't seem to find these limitations discussed in the spec.
Edit : Sorry, I should have been specific on the return value. Assuming the function returns a function pointer, is it possible to dereference and call the result within the same statement, in fluent fashion?
For example, assuming getFunc returns a function pointer :
(*getFunc(getFuncParam))(otherFuncParam)
Or in the struct case, assuming a struct with an int member called count:
funcReturnsStruct(param).count++
Here's what function chaining looks like in C:
post_process(process(pre_process(data)));
Obviously, your friend is wrong. As long as the functions cooperate by accepting and returning the same type of value you can chain the calls all you like.
Contrast this with something like
data.pre_process().process().post_process();
The big difference is that in C (which has no encapsulation, hence no classes) functions have center stage while in more modern OO languages it's objects that get more attention.
Update: Sure it's possible to chain no matter what each function might return. For example:
int increase(int x) {
return x + 1;
}
typedef int (*increase_fp)(int);
increase_fp get_increase() {
return increase;
}
int main(void) {
printf("%d", get_increase()(1));
return 0;
}
See it in action.
a friend of mine where he told me that given a function returning a struct, you cannot perform any operations on said struct within the same statement
Your friend is correct in the sense that the return value of a function cannot be the target of an assignment (it's not an lvalue). IOW, you can't do something like
int foo(void) { int x = 5; return x; }
...
foo() = 6;
However, if the return type of a function is a struct or a union, you can apply the component selection operator to the return value, such as
int x = foo().memb;
Similarly, if the return type of the function is a pointer to a struct or a union, you can write
int x = foo()->memb;
And if the return value is a pointer to another function, you can call that other function like so:
int bar(int x) { ... }
int (*foo)(int x) { return bar; }
int x = foo(x)(y); // or (*foo(x))(y) -- the result of foo(x) is
// called with the argument y
although anyone who has to maintain or debug your code may beat you severely for it.
What you cannot do is something like
foo().memb= ...;
foo()->memb = ...;
which wouldn't make sense anyway, because the lifetime of the value returned by foo ends when the statement ends - you wouldn't be able to retrieve that modified value.
Your friend is wrong.
If we have:
struct Point3
{
float x, y, z;
};
const Point3 * point3_get_origin(void);
then you can certainly do:
printf("the origin's y coordinate is %f\n", point3_get_origin()->y);
The function returns a value of the given type, so the call of the function can be used wherever such a value is needed in an expression.
Do you mean something like this?
typedef void (*CALLBACK)(void);
CALLBACK getCallback();
void test()
{
getCallback()();
}
It compiles with no warning in GCC 4.6.1 (default std).
There's a much faster and easier way to answer this than posting here: try it.
#include <stdio.h>
struct s {
int a;
} s;
struct s * getS() {
s.a = 13;
return &s;
}
int main(int argc, char * const argv[]) {
printf("%d\n", getS()->a);
return 0;
}
% gcc test.c -o test -Wall -pedantic
% ./test
13
%
Not so much as a pedantic warning. Expected output. Looks like it's perfectly fine. However, as has been pointed out, it would be better to store the return value and check for errors.

How to return a value to the calling function without using return statement?

The function proto type like int xxxx(int) or void xxx(int)
You could use a global variable (or, a little better, you could use a static variable declared at file scope), or you could change your functions to take an output parameter, but ultimately you should just use a return statement, since that's really what it's for.
The two standard ways to return values out of functions in C are to either do it explicitly with the return statement, or to use a pointer parameter and assign into the object at the pointer.
There are other ways, but I'm not going into them for fear of increasing the amount of evil code in the world. You should use one of those two.
Use pass by reference:
void foo(int* x, int* y) {
int temp;
temp = *x;
x* = *y;
y* = temp;
}
void main(void) {
int x = 2, y=4;
foo(&x, &y);
printf("Swapped Nums: %d , %d",x,y);
}
You could have a global variable that you assign the value to.
You could pass an object that stores the integer, and if you change it in the function, it'll change elsewhere too, since objects are not value type.
It also depends on the programming language that you're using.
EDIT: Sorry I didn't see the C tag, so ignore my last statement
Typically you provide a reference to an external variable to your function.
void foo(int *value)
{
*value = 123;
}
int main(void)
{
int my_return_value = 0;
foo(&my_return_value);
printf("Value returned from foo is %d", my_return_value);
return 0;
}
The simple answer is given a prototype like the first one you must use the return statement as the int return value dictates it.
In principle it is possible to do something horrible like cast a pointer to an int and pass it in as a parameter, cast it back and modify it. As others have alluded to you must be sure you understand all the implications of doing this, and judging by your question I'd say you don't.
int wel();
int main()
{
int x;
x = wel();
printf("%d\n",x);
return 0;
}
int wel()
{
register int tvr asm ("ax");
tvr = 77;
}
Compiled with GCC compiler in ubuntu machine. In borland compiler, different way to return.
If you need to return more than one value, why not use a pointer to a new allocated struct?
typedef struct { int a, char b } mystruct;
mystruct * foo()
{
mystruct * s = (mystruct *) malloc(sizeof(mystruct));
return s;
}
Not tested, but should be valid.

Resources