2

I am completely new to structs and user defined datatypes, and i was trying to create a function that returns a struct:

The problem is highlight by the comment:

#include <iostream>

using namespace std;

struct num {
    int n[2];
};

num func( num x, int a, int b) {
    x.n[0] = a+b;
    x.n[1] = a*b;
    return x;
}

int main() {
    int x,y;
    num s1;
    cout << "enter: ";
    cin >> x >> y;
    func(s1,x,y);
    cout << s1.n[0] << "\n" << s1.n[1];        // THIS GIVES ERROR
    cout << func(s1,x,y).n[0] << "\n" << func(s1,x,y).n[1];  // THIS DOENST GIVE ERROR
    return 0;
}

I understand that second method makes sense and returns the struct variable. then putting a dot addresses the inner variable of struct.

But i dont understand why first method fails, or gives odd output. The function has done its job, ie made s1.n[0] = x + y and s1.n[1] = x*y
Now, printing s1.n[0] should print x + y only. How can we check and correct the internal workings of the function?

2
  • Which error exactly? Provide a minimal reproducible example as usual please. Commented Oct 25, 2015 at 16:00
  • @πάνταῥεῖ: The problem is obvious and clear. And, well, this is an MCVE anyway. Commented Oct 25, 2015 at 16:03

4 Answers 4

3

You have to assign the returned value to the structure object in main

s1 = func(s1,x,y);

Inside the body the function deals with a copy of the original object. It does not change the original object because it is passed by value.

Another approach is to pass the structure by reference

void func( num &x, int a, int b) {
    x.n[0] = a+b;
    x.n[1] = a*b;
}

In this case in main you could just write

func(s1,x,y);

Or you could use even so-called C approach of passing by reference

void func( num *x, int a, int b) {
    x->n[0] = a+b;
    x->n[1] = a*b;
}

and call it like

func( &s1, x, y );

As for this statement

cout << func(s1,x,y).n[0] << "\n" << func(s1,x,y).n[1];  

then you access data members of two temporary objects returned by the two calls of the function. After executing this statement these temporary objects will be deleted.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you but why is this done? isnt the function doing this?
@TimKrul: No. Your code takes a copy of your num, modifies it then returns it. Your main function does nothing with this new modified version.
Oh i didnt give much attention to call by value class. Thank you!
3

It looks like you are never assigning the return value of func(). Your function returns the struct, but you are never assigning it. To fix this, you should be able to simply say: s1 = func(s1,x,y); This will assign the modified version of the struct to the s1 variable.

Alternatively, you could rewrite func() to accept a pointer to the struct. This would allow you to modify the struct without having to return it:

 void func( num *x, int a, int b) {
     x->n[0] = a+b;
     x->n[1] = a*b;
 }

Then you would just change your call to func() to say: func(&s1, x, y);

Comments

2

You are not passing your struct by reference, hence the result. Try the following:

void func(num &x, int a, int b) { 
    x.n[0] = a+b;
    x.n[1] = a*b;
}

There's no need for the function to return anything since your struct is passed by reference and it will be changed anyway. Void would fit better.

1 Comment

Why keep the return type of num, then? It's never used. Vlad's answer is better.
1

This is because you have passed the struct by value while your intentions look like you want to pass by reference. Check this link : http://courses.washington.edu/css342/zander/css332/passby.html

num func( num &x, int a, int b) 

should fix your problem

3 Comments

Why keep the return type of num, then? It's never used.
@LightnessRacesinOrbit that depends on the use cases of func. From the question it looked like the OP was confused about semantics of passing parameters to function. There are precedents to cases where an object returns an instance and modifies the parameter that is passed to it.
Of course there are, but the "default" approach should be the clear and simple one, which is using the return value the OP's already got. Your answer keeps that value, but makes it completely redundant; that seems like a backwards step, to me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.