K. West
K. West

Reputation: 3

In, Out, In/Out parameters

I have a test coming up and I would like some clarification on two questions regarding parameters.

In my notes it states that the recommended way to pass a parameter to a function would be to use "pass by reference"

    const type& x; // for "in" parameters
    type& x; // for "out"(to read) and "in/out"(to read/write) parameters

It also states for optional optimization, we can pass "in" parameters by value and we can also pass the out variable by reference instead of a simple return.

On the review question I'm trying to answer it states

Assume that all types are “moderate” size: Do not use the small-value optimization or the big-value optimization.

Would the reference to "moderate size" mean I would use a pass by reference for "in" and "in/out" parameters as well as using basic return for "out" values?

Further more, there is a question that ask to create a prototype function (no body) that has the following:

IN : string a, C b
OUT : double d
IN/OUT : string d

    double foo (const string& a, const C& b, string& d)

is what I have right now but I'm not sure how to handle the OUT and the IN/OUT since they are given the same name. Am I right to assume that a reference to the string could be passed into the function and a function like stod() is used to to generate a return of type double which can be stored in the calling function like

    double val = foo(x,y,z)

Upvotes: 0

Views: 6123

Answers (1)

txtechhelp
txtechhelp

Reputation: 6777

I won't get into immutable types or any other lower level language semantics since you're still learning about the basics of passing values around, so I'll answer your questions as direct as possible and leave it to you to ask your instructor for more info on the topics (as well to hopefully not confuse you for you test).

Would the reference to "moderate size" mean I would use a pass by reference for "in" and "in/out" parameters as well as using basic return for "out" values?

Based on the context of what you're learning right now, I would say no that the size that it's refering to is the sizeof(X) where X is the type you're passing in/out. So in the instance of an int, doing a pass-by-value or a pass-by-reference has no real additional costs to memory or CPU time, but if I had something like the following:

struct SomeLargeStruct {
    char SomeChars[1000];
    int SomeInts[1000];
    double SomeDoubles[1000];
};

The sizeof(SomeLargeStruct) would be rather large and incur a large construction time if we pass-by-value (because of the copy that would happen), example:

void incurACopy(SomeLargeStruct s) { /* do something with s */ }
void giveMeDirect(SomeLargeStruct& s) { /* do something with s */ }

SomeLargeStruct c;
incurACopy(c); // a copy of c is made, lots of data being passed
giveMeDirect(c); // the location of c is passed on the stack, no copy made

So for "in" types, you give const type& to state to the user of the code that the value passed in must be a valid reference (i.e. it must not be null) and since it's const qualified, we can be assured that the code taking the reference to our type won't/can't modify the data, that is, it's read-only.

The "out" type is type& because this signifies that the value being passed in could be modified by the function. Doing this versus a return might be less costly if the type is a large (i.e. sizeof) type and there are any temporaries involved in the return type, otherwise there might not be much of a difference (you'd have to inspect the low level assembly to be sure).

As for "in/out" types, you could use type& again to signify that the value could be modified, though anecdotally I've seen "in/out" types more often referred to as "optional" types, that is, an "in/out" type could be an optional parameter that has a default value if none passed in, otherwise the value passed in has an affect and thus could be modified.

The could modifier for the "out" and "in/out" types is there because it would be left to the implementer of the function to document the fact that the value might change, in other words, it's possible they just forgot to put const in front of the type&.

Given this, as per your other question with regards to the prototype, I'd wager that the OUT : double d and IN/OUT : string d is a typo, otherwise, you could always just write 2 function prototypes:

double foo (const string& a, const C& b, string& d);
double d = foo(x, y, z); // double d ??

and/or

void foo(const string& a, const C& b, double& d, string& s)
{
    cout << "IN/OUT string d maybe string s?" << endl;
}

But to be safe, you should probably double check with your instructor (after all, you might not be the only one struggling with that possible typo).

Hope that can help and good luck with your test.

Upvotes: 1

Related Questions