0

I'm new at programming. This is part of my code:

double logic(double a,double b)

{
    (Code Here...)
}
double inputDouble(double x)

{
    std::cout << "Please, input a floating number: ";
    std::cin >> x;
    std::cout << std::endl;
    return x;
}
int main()

{
    double a,b;
    std::cout << logic(inputDouble(a),inputDouble(b));
    return 0;
}

I've noticed the problem on the compiler, them I've checked the debug windows and the problem that I'm having is that when I insert a value on 'a' by 'inputDouble' function, it goes to 'b', and vice-versa. So at the end of the program what I get in 'logic' function is: double a=b(From main()), double b=a(From main()). I hope and am grateful to someone who can explain to me what I'm doing wrong so the variables are being assigned on the wrong places. And I also apologize if there is any gramatical mistake on this post as english is not my first language.

  • 4
    C++ makes no guarantees about the order in which arguments are evaluated. So when you write the call `logic(inputDouble(a), inputDouble(b), inputSignal())`, there's no guarantee that it'll figure out `inputDouble(a)` first, then `inputDouble(b)` second, then `inputSignal()` third. If you want to enforce that order, perform those calls in `main`, save the results to variable, and then call `logic(a, b, signal)` or something. – Nathan Pierson Oct 12 '20 at 00:39
  • 1
    One other observation is that `inputDouble` doesn't actually use its argument, it just uses it as a way to store a `double`. You could have written it as `double inputDouble()` and then had a function local variable `x`, the way you have `a` and `b` in `main`. (If you thought `inputDouble`'s effect was to save the input from `cin` to the argument `x`, that's not what's happening--look up passing by value and passing by reference.) – Nathan Pierson Oct 12 '20 at 00:41
  • @Nathan Pierson Thank you for your answer. This certainly helps to understand the problem and how to solve it, but still, the problem I'm having here is that when I try to pass the values a and b from a function to another it reverses their order... Isn't there anything I could do to solve it? If there isn't them it is just sad :( – Rafael Ferreira Oct 12 '20 at 00:44
  • @StephenNewell Thank you for your answer. Sorry, I'm a new programmer and your link seem to have some advanced stuff and concepts so I couldn't be able to understand it. – Rafael Ferreira Oct 12 '20 at 00:46
  • 1
    @NathanPierson, wow it really worked :O Thank you for helping me, it seems it was a logical error from my part. Many thanks – Rafael Ferreira Oct 12 '20 at 00:51
  • [function parameter evaluation order](https://stackoverflow.com/q/9566187/995714), [Why doesn't c++ have a specified order for evaluating function arguements?](https://stackoverflow.com/q/38764793/995714) – phuclv Oct 12 '20 at 03:56

1 Answers1

3

The expression:

logic(inputDouble(a),inputDouble(b))

does not guarantee the order in which those calls to inputDouble() are made, just that they're both complete before the call to logic(). So it may call the a one first, or it may call the b one first(a).

To guarantee order, you can use something like:

double inputDouble() { // slight change, see below.
    double x;
    std::cout << "Please, input a floating number: ";
    std::cin >> x;
    std::cout << std::endl;
    return x;
}

int main() {
    double a = inputDouble(); // guarantee get 'a' first.
    double b = inputDouble();
    std::cout << logic(a, b);
    return 0;
}

You could also use:

    double a = inputDouble();             // guarantee get 'a' first.
    std::cout << logic(a, inputDouble());

but I prefer the first one for consistency.


You'll notice a slight change to the inputDouble() function as well to remove the parameter, no useful purpose is served by passing the uninitialised values to the function, then over-writing and returning it.

Instead, I've just used a local variable to receive the value and return it.

A more robust program would also ensure that user input was valid but that can be left for a different question, since it almost certainly already exists on this site.


(a) For the language lawyers amongst us, this is covered in C++20 [expr.call] /8 (my emphasis):

The initialization of a parameter, including every associated value computation and side effect, is indeterminately sequenced with respect to that of any other parameter. [Note: All side effects of argument evaluations are sequenced before the function is entered].

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • I actually didn't even realize C++ would let you pass uninitialized variables by value to a function. Although I suppose a compile-time check is the halting problem and a runtime check is never performed because it's never read from? Surprising behavior in any case. – Nathan Pierson Oct 12 '20 at 00:49
  • 1
    @Nathan: whether it's read from is not an issue to the compiler. C++ will make the assumption developers are following the rules, which allows it to make certain assumptions for performance. – paxdiablo Oct 12 '20 at 00:53
  • Thank you, that was the solution for my problem! – Rafael Ferreira Oct 12 '20 at 00:53