1

Why and how did the program give the output?

#include <stdio.h>
int sum(int a ,int b , int c ){
    return a , b ,c;
}
int main() {
    int a=10, b=100 , c=1000 ;
    int x = sum(a , b ,c);
    printf("%d %d %d" ,x);
    
    return 0;
}

Output : 1000 1000 100

ChrisMM
  • 8,448
  • 13
  • 29
  • 48

4 Answers4

6

Wow. This is a spectacularly misleading result.

No, you can not return multiple values like this in C. A function can have at most one single return value. You can't use a comma to return multiple values like this.

But, if you can't do it, then why did it seem to almost work? That's a rather complicated question, that it probably won't be possible to completely answer here.

Your program has two, completely unrelated problems. The first problem, which isn't too serious, is the line

return a, b, c;

at the end of function sum. In English, this line basically says, "Take the value a and throw it away, then take the value b and throw it away, then take the value c and have it be the actual return value." (See What does the comma operator do? for more about this comma operator.)

And then the second, much more serious problem is the line

printf("%d %d %d", x);

in main. Your compiler should have warned you about this problem; mine says warning: more '%' conversions than data arguments. You're telling printf, "I'm going to give you three int values to print". But you lied, because you're then giving it just one int value, x. So printf is blindly reaching for the other two values you promised, and getting... what?

By a reasonably incredible coincidence, when printf reaches out to fetch the values you didn't pass, it is somehow grabbing... one of the values that got thrown away by the poorly-written return statement back in function sum. I'm not even sure how this happened, although when I tried your program on my computer, I got a similar result.

This may be too obvious to mention, but: this result is not guaranteed, it's not something to depend on, and it's not even something to learn from. If you want to return multiple values from a function, there are other ways to do that, as this question's other answers have suggested.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
  • About the "spectacular" result, it may be interesting to note that on my GCC with `-O0`, I get OP's result, while starting from `-O1` onward, I get garbage values. The key difference is that with `-O0`, GCC puts `a` and `b` on the stack, while starting from `-O1`, GCC simply translates `return a, b, c;` to `return c;`. – Luca Polito Oct 03 '21 at 15:02
4

Short answer: no, you cannot return multiple values (at least, not as you did). Good news, you do have some ways to return multiple values from a function:


Method 1: use a struct

typedef struct result {
  int a;
  int b;
  int c;
} result_t;

result_t foo(int a, int b, int c) {
  return (result_t) { a + 1, b + 1, c + 1 };
}

int main(void) {
  result_t res = foo(1, 2, 3);
  printf("res.a is %d\n", res.a); // OUTPUT: res.a is 2
  return 0;
}

Method 2: use pointers as function arguments

void some_calc(int input, int* output1, int* output2) {
  *output1 = input * 2;
  *output2 = input / 2;
}

int main(void) {
  int res1, res2;
  some_calc(50, &res1, &res2);
  printf("50 * 2 = %d and 50 / 2 = %d\n", res1, res2);
  return 0;
}
Luca Polito
  • 2,387
  • 14
  • 20
1

One way to achieve with structs,

#include <stdio.h>

    struct Values
    {
        int a;
        int b;
        int c;
    } values;
    
    
    struct Values sum(int a ,int b , int c ){
        return (struct Values){ a, b, c};
    }
    
    int main() {
        int a=10, b=100 , c=1000 ;
        struct Values x = sum(a , b ,c);
        printf("%d %d %d\n" ,x.a, x.b, x.c);
        return 0;
    }
pvc
  • 1,070
  • 1
  • 9
  • 14
1

This statement

printf("%d %d %d" ,x);

invokes undefined behavior because the number of arguments is less than the number of conversion specifiers.

In the return statement of the function

int sum(int a ,int b , int c ){
    return a , b ,c;
}

there is used the comma operator. The value of an expression with the comma operator is the value of the right-most operand. So in fact you have

int sum(int a ,int b , int c ){
    return c;
}

From the C Standard (6.5.17 Comma operator)

2 The left operand of a comma operator is evaluated as a void expression; there is a sequence point between its evaluation and that of the right operand. Then the right operand is evaluated; the result has its type and value.

The function should look like

int sum(int a ,int b , int c ){
    return a + b + c;
}

of if to avoid a possible overflow then

long long int sum(int a ,int b , int c ){
    return ( long long int )a + b + c;
}

and in main you have tp write

printf("%lld\n", x );

If you want to return several objects from a function then a simplest way is declare a structure that contain the number of data members equal to the number of objects that you are going to return

For example

struct tuple
{
    int a;
    int b;
    int c;
};

struct tuple f( int a, int b, int c );
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • I do like your answer, and I'm sorry if I sound pedantic, but just a little note: using `long long` to calculate `a + b + c` is not *always* going to avoid integer overflow, because `int` may be 64-bit, and `long long` may be 64-bit as well. There are stronger methods to detect overflow in arithmetic (like GCC's function `__builtin_sadd_overflow()`). Some of these may even be included in the next C standard. (But yes, *for most platforms* your method is correct). – Luca Polito Oct 03 '21 at 15:12