Compiling your code with warnings enabled produces this output:
chqrlie> clang -Wall -Werror 230312-triplet.c
230312-triplet.c:9:12: error: left operand of comma operator has no effect
[-Werror,-Wunused-value]
return var1, var2, var3;
^~~~
230312-triplet.c:9:18: error: left operand of comma operator has no effect
[-Werror,-Wunused-value]
return var1, var2, var3;
^~~~
230312-triplet.c:16:5: error: left operand of comma operator has no effect
[-Werror,-Wunused-value]
x, y, z = Function(x, y, z);
^
230312-triplet.c:16:8: error: left operand of comma operator has no effect
[-Werror,-Wunused-value]
x, y, z = Function(x, y, z);
^
230312-triplet.c:16:24: error: variable 'x' is uninitialized when used here
[-Werror,-Wuninitialized]
x, y, z = Function(x, y, z);
^
230312-triplet.c:14:10: note: initialize the variable 'x' to silence this warning
int x, y, z;
^
= 0
230312-triplet.c:16:27: error: variable 'y' is uninitialized when used here
[-Werror,-Wuninitialized]
x, y, z = Function(x, y, z);
^
230312-triplet.c:14:13: note: initialize the variable 'y' to silence this warning
int x, y, z;
^
= 0
230312-triplet.c:16:30: error: variable 'z' is uninitialized when used here
[-Werror,-Wuninitialized]
x, y, z = Function(x, y, z);
^
230312-triplet.c:14:16: note: initialize the variable 'z' to silence this warning
int x, y, z;
^
= 0
7 errors generated.
It is a pity warnings are not enabled by default!
What this means is return var1, var2, var3; does not return 3 values, but evaluates the comma operator expression var1, var2, var3, which evaluates to its last operand var3, and returns this value 3 as the function return value.
Similarly, x, y, z = Function(x, y, z); does not implement parallel stores of the 3 values, but again evaluates a comma expression which according to the operator precedence rules is parsed as:
x, y, (z = Function(x, y, z));
x and y evaluate to their values which are ignored (but would have to be read were they qualified as volatile, and z = Function(x, y, z) finally stores 3 to z. Note also that x, y and z are passed to Function but are not initialized so merely passing their values has undefined behavior.
As explained by @AndreasWenzel, a function can return multiple values by returning a structure, or updating values in the calling scope via pointers.
The latter is more idiomatic for separate variables:
#include <stdio.h>
void intialize(int *a, int *b, int *c) {
int var1 = 1;
int var2 = 2;
int var3 = 3;
*a = var1;
*b = var2;
*c = var3;
}
int main() {
int x, y, z;
initialize(&x, &y, &z);
printf("%d %d %d\n", x, y, z);
return 0;
}
Output:
1 2 3
Grouping the variables in a structure may be more consistent for variables describing the same object:
#include <stdio.h>
typedef struct object {
int x, y, y;
} object;
void object_initialize(object *obj) {
obj->x = 1;
obj->y = 2;
obj->z = 3;
}
int main() {
object o;
object_initialize(&o);
printf("%d %d %d\n", o.x, o.y, o.z);
return 0;
}
Output:
1 2 3