-1

I tried to change simple if/else statement into ternary but after typing it as:

cout << endl
         << "1. Another equation" << endl
         << "2. Exit Calculator" << endl;
    int afterCalc;
    cin >> afterCalc;

    (afterCalc == 1)? goto calcStart : continue;

I get "expected expression" notice and code doesnt debug/compile. Is there sth wrong with the code or it's VSC bug?

pszym
  • 29
  • 3
  • 2
    `goto` really? What you should use here is not the ternary operator but just a while loop. [goto is considered harmful and should not be used](https://stackoverflow.com/questions/46586/goto-still-considered-harmful). – Pepijn Kramer May 25 '23 at 11:16
  • 9
    The first rule of programming: [It's Always Your Fault](https://blog.codinghorror.com/the-first-rule-of-programming-its-always-your-fault/). `goto` is a statement, not an expression, and it cannot be used in conditional (ternary) operator – Yksisarvinen May 25 '23 at 11:16
  • The only alternative to an expression yielding a value that can be used in the alternatives of the tenary operator is a `throw` expression. `goto` isn't one of those. You're stuck with good ol' `if ... else ...`. (But better rewrite the code and the pasta... – fabian May 25 '23 at 11:19
  • 2
    Thanks guys. It's alway your fault - I'll remember :) – pszym May 25 '23 at 11:25
  • 1
    Totally offtopic but you should also [avoid endl](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rio-endl) and (just in case you did it) not write [using namespace std;](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice). – Friedrich May 25 '23 at 11:30
  • Don't abuse the poor conditional operator like that. Such code is what gives it a bad reputation. – molbdnilo May 25 '23 at 11:34
  • Same is true of `continue`, that also is not an expression. – john May 25 '23 at 11:51
  • You might want to turn `continue` into `goto some_label` and use syntax described [here](https://stackoverflow.com/q/1777990/509868) for a computed `goto`. But this technique is rarely useful; surely not useful in your case. – anatolyg May 25 '23 at 12:26
  • @Friedrich avoid endl beacause it's in namespace std or is there another reason? – pszym May 25 '23 at 12:31
  • 1
    `endl` forces a flush of the stream. This is a costly (time) operation that is not needed on each line. – drescherjm May 25 '23 at 12:50
  • 1
    @pszym what drescherjm says. Namespace `std` is fine and contains a lot of great stuff. In my comment, there's a link behind `endl` which explains it. Almost as if I put it there on purpose :) – Friedrich May 25 '23 at 13:12
  • Oh, another thing. Don't invalidate your own question by calling it a "newbie question". Everybody is or was new to something at some point. No shame in that. It does however invite downvotes and decreases your chances of getting a good answer. – Friedrich May 25 '23 at 13:18
  • got it. thanks again @Friedrich and everyone :) I'm surprised with this supportive attitude, as this is my first inquiry here. I'll try not to overexploit that! – pszym May 25 '23 at 14:24
  • 2
    My #1 motivation in commenting and participating is to help make you and other readers who follow along better programmers. I appreciate your attitude in accepting all of the constructive criticism. I know it can be a bit overwhelming at times with so much advice we give.. – drescherjm May 25 '23 at 14:58

2 Answers2

2

The conditional operator requires expressions as its operands. goto and continue are statements and not expressions, so the operator can't work with any of them.

Statements are instructions for the program - "what to do"; they usually end with a semicolon ; or a closing brace }.

Expressions are fragments of code whose value should be used — in other expressions or in statements. It doesn't make sense to use flow control instructions in an expression.

See cppreference for more info.


You should make code readable, as a general guideline. This is even more important if you really must use goto and continue — these rare cases are when the code does some obscure and important stuff, and you should try to use the most readable way to express your code! That is, leave it as if-statement, and maybe add comments to explain what your code does.

Alternatively, rewrite your code so that it doesn't use goto.

anatolyg
  • 26,506
  • 9
  • 60
  • 134
1

The ternary operator is not for control flow. The ternary operator, while being able to accommodate code within the conditions, is an assignment that produces an lvalue.

I'm not sure why you would want to change an if/else in this case, but one way to do it (perhaps not the cleanest) is:

void *something_else() {
    cout << "Do something useful here" << endl;
    return nullptr;
}

int main() {
    int afterCalc;
    do {
        cout << endl
            << "1. Another equation" << endl
            << "2. Exit Calculator" << endl;
        cin >> afterCalc;
        void *foo = (afterCalc == 1) ? something_else() : nullptr;
    } while(afterCalc == 1);
}

I don't know your use case and I would not do this, but it works. BOTH of the LVALUE's must be the same data type, hence the need to return a void pointer.

  • You don't even need to fake and assign a return value; you can use `void` type instead: `cin >> afterCalc; afterCalc == 1 ? something_else() : void();` but it's still uglier than proper flow control with `if`. – anatolyg May 25 '23 at 18:51