Reputation: 579
Here is a C function that returns an array with a type defined in a struct. It successfully returns the array p. My question: can I eliminate p and do a return as shown in the commented-out statement?
#include<stdio.h>
typedef struct {
int dy, dx, iter;
} M;
M *boom (int x) {
// I'm happy with this approach
static M p[] = { {+5, +6, +7}, {+1, +1, +0}, {+3, +3, +3} };
return p;
// but I'm keen to know how this can be done.
// return { {+5, +6, +7}, {+1, +1, +0}, {+3, +3, +3} }; // causes error
}
int main() {
M *result = boom(1);
printf("First element %d\n", result[2].dy);
}
I get "error: expected expression before '{' token" for the line I've commented out.
Upvotes: 1
Views: 777
Reputation: 23218
No, but you can return a pointer to any construct, including arrays and structs using identical approaches. eg:
Given the prototype M *boom (int x)
, the following demonstrates how you can pass back an instance of M
struct data after having modified it.
typedef struct {
int dy, dx, iter;
} M;
M *boom (int x) {
M *new = malloc(sizeof(*new));
if(new)
{
//modify new instance of M
new->dx = x;
//and so on
}
return new;
}
int main() {
M *result = boom(1);
printf("First element %d\n", result[2].dy);
free(result);
}
This method can be used exactly the same way with arrays:
Given the following function:
int * func(int *array, size_t size, int index, int newValue)
{
int *newArray = malloc(size * sizeof(*newArray));
//modify as much of original array as needed:
newArray[index] = newValue;
return newArray;
}
In main():
int *a = func(array, sizeof(array), 2, 100);
printf("new value for element %d is %d\n", 2, a[2]);
free(a);
Upvotes: 1
Reputation: 31389
No you cannot.
The closest I can think if that you can return a compound literal. Example:
struct myStruct {
int x;
int y;
};
struct myStruct foo() {
return (struct MyStruct) {.x =5, .y=6};
}
But you cannot do this with arrays. As Eric Postpischil said in the comments:
To be clear, this is not because compound literals cannot be arrays. They can. It is because an array cannot be returned by value, and its address, or the address of its first element, cannot properly be returned because the array’s lifetime would end with the function return.
Something that is possible if you restrict yourself to fixed size arrays is to wrap the array in a struct:
struct myStruct {
int x;
int y;
};
struct myContainer {
struct myStruct arr[3];
};
struct myContainer foo() {
return (struct myContainer) {
.arr={{.x =5, .y=6}, {.x=4, .y=1}, {.x=42, .y=665}}
};
}
I might also mention that even if returning addresses to local static variables is perfectly legal, it is widely considered a strong code smell.
Upvotes: 3
Reputation: 424
Array literals can only be used for initialization. They can't be passed around like string literals or integers or floats.
Upvotes: 1