0

I am fairly new to C++ and have been tinkering with some simple programs to teach myself the basics. I remember a little while ago installing MinGW on my desktop (I think for the C compiler). I decided to go for Cygwin for C++ and it seems to have been working a treat, up until I noticed that it seems to behave differently from the MinGW compiler for this program. I'm probably breaking some coding golden rule, but the reason for this is that Windows CMD uses the MinGW compiler, or I can open the Cygwin shell and use that instead. Variety!

For the program below, I am making notes on the ternary operator and switch statement. I initialize 'a' and 'b', ask for user input, and then use a function to check which is larger.

I then ask for user input again, to over-write the values in 'a' and 'b' to something else. When compiling from Windows CMD, this works fine and I can overwrite with new input, and the #define MAXIMUM and MINIMUM functions work fine on the new values. When I compile on Cygwin, however, after the first 'pause', the program launches past the two std::cin's and just runs MAXIMUM and MINIMUM on the old values of 'a' and 'b'.

Obviously I have tried just creating two new int variables, 'c' and 'd', and then there is no issue. The values are not immutable in any sense that I am aware of (although I don't know much, so I could be wrong).

I wasn't sure if this was something to do with the auto keyword, so I specified the type as int manually.

I also checked the version of both compilers with 'g++ -v' in Cygwin and at the CMD.

#include <iostream>
#include <cstdlib>

#define MAXIMUM(a,b) ((a > b) ? a : b)
#define MINIMUM(a,b) ((a < b) ? a : b)

int ternary_op(int a, int b)
{
    char x = 'a';
    char y = 'b';
    auto result_var = 0;

    result_var = a > b ? x : y;     //Shorthand if statement with syntax   (test_condition) ? (if_true) : (if_false)

    return result_var;
}

int main()
{
    auto a = 0;
    auto b = 0;
    auto larger  = 0;
    auto smaller = 0;

    std::cout << "Enter an integer: " << "\n";
    std::cin >> a;
    std::cout << "Enter another integer: " << "\n";
    std::cin >> b;

    char greater_var = ternary_op(a,b);        //Therefore if condition a > b is satisfied, greater_var is assigned x ('a')
    std::cout << greater_var << std::endl;

    switch(greater_var){

        case 'a':
            std::cout << "First integer " << a << " is larger than second, " << b << std::endl;
        break;

        case 'b':
            std::cout << "Second integer " << b << " is larger than first integer, " << a << std::endl;
        break;

    }

    std::cout << system("cmd /c pause") << std::endl;

    std::cout << "We can also use defined functions to check equivalency and assign variables based upon the result." << "\n";

    std::cout << "Enter an integer: " << std::endl;
    std::cin >> a;
    std::cout << "Enter another integer: " << std::endl;
    std::cin >> b; 

    larger  = MAXIMUM(a,b);
    smaller = MINIMUM(a,b);

    std::cout << "Larger and smaller numbers determined by defined function: " << larger << ", " << smaller << std::endl;
    std::cout << system("cmd /c pause") << std::endl;

    return 0;

}

Obviously if I make two new variables, 'c' and 'd', there is no issue. Changing the type to int myself did not change the way the program behaved using Cygwin. Unusually the MinGW version was 8.1.0, while Cygwin was 7.4.0. I'm not sure if this means that it is simply an older version of the same compiler.

Again, I'm very new to this so I'm just quite confused as to why they would behave so differently. I was also under the impression that different compilers were completely different beasts that simply read from the same standard hymn sheet, so to speak.

Just curious as to what is going on here!

Cheers!

Rowan
  • 351
  • 2
  • 13
  • *the program launches past the two std::cin's and just runs MAXIMUM and MINIMUM on the old values of 'a' and 'b'.* Shouldn't happen unless `cin` is in a fail state, but in this case using new variables wouldn't change a thing. Whether `a` or`c` is there is completely irrelevant. They're just containers for the output of `>>` – user4581301 Sep 08 '19 at 18:03
  • Hi, thank-you for the comment, What would cause the input to fail in the way that you describe? I have written simple programs that re-use variables several times and this is a fresh issue. Rowan. – Rowan Sep 08 '19 at 18:05
  • What is the output of `std::cout << system("cmd /c pause") << std::endl;`? `system` isn't all that well defined because all systems are different. [It's best avoided in fact.](https://stackoverflow.com/questions/19913446/why-should-the-system-function-be-avoided-in-c-and-c) What happens if you use a more civilized `std::cout << "Hit enter to continue, monkeyboy!" << std::endl; std::string junk; std::getline(std::cin, junk);` and stay within the C++ runtime? – user4581301 Sep 08 '19 at 18:09
  • `system("cmd /c pause")` is an alternative to the Windows CMD `system("pause")`. Both produce this output: `Press any key to continue . . . ` Thanks for the suggestion! (good laugh, too). I will try your solution now and see what changes. Edit: Seems that the `system` call was the problem! I replaced it with simply input into a throwaway string variable as you suggested and the issue seems to have resolved on Cygwin. The only downside to this approach is typing a character and pressing enter, as opposed to simply pressing any key as before. Oh well, at least it works! – Rowan Sep 08 '19 at 18:13
  • Oops, I hadn't used `std::getline`; Your solution actually works perfectly. – Rowan Sep 08 '19 at 18:20
  • `system` returns an implementation defined value as an `int`. You should be seeing that `int` printed out somewhere. There is no need to `cout` anything, but I am interested in where that `int` is and what value it is. Part of what's interesting here is mingw is compiling for Windows and `cmd` almost makes sense. Cygwin compiles for a POSIX wrapper around Windows and I'm not sure how much sense calling `cmd` makes. – user4581301 Sep 08 '19 at 18:20
  • Sounds like jumping out of your program in Cygwin-space, into Windows space to run a command console, and then dropping back into the program mangled the state of the input stream. I have no explanation for that. Might be a Cygwin guru around here somewhere who can explain it though. – user4581301 Sep 08 '19 at 18:23
  • That makes some sense. Thankyou for your response and solution on this. I believe that is exactly what it was doing. As for the `int`, I imagine here that refers to the zeros: `First integer 389 is larger than second, 67 Press any key to continue . . . 0 We can also use defined functions to check equivalency and assign variables based upon the result. Enter an integer: Enter another integer: Larger and smaller numbers determined by defined function: 389, 67 Press any key to continue . . . 0` - Which, to my untrained eye, indicates a success (although clearly not!) – Rowan Sep 08 '19 at 18:27
  • To test that theory, print out `cin.good()`, (and maybe `eof()`, `fail()`, and `bad()` to see if there's more information to be had) after `std::cout << system("cmd /c pause") << std::endl;` to see what state `cin` is in. If `good` returns `true`, you should be able to read and I might have a symptom, but not the true problem. – user4581301 Sep 08 '19 at 18:28
  • 0 usually means success. Most often `system` returns the result code of the executed process and `return 0;` is traditional for "It works." – user4581301 Sep 08 '19 at 18:29
  • Actually, you shouldn't do stuff like `system("pause")`, `getchar()` or `std:.getline()` at all if it just serves for keeping some console window open. That's not the task of a console application and just prevents that you can use the console programme from within some script. Better: Open a console manually and start your programmes from within. – Aconcagua Sep 08 '19 at 18:29
  • Another note: `system` calls the system's command processor, so what `system("cmd /c pause")` is probably doing is invoking `cmd /c cmd /c pause`. – user4581301 Sep 08 '19 at 18:35

0 Answers0