0

Assume it is valid C++ to include declaration inside the if condition (reference)

The following code segment compiles with a warning about the unused variable k (warning: unused variable ‘k’ [-Wunused-variable])

#include <iostream>
using std::cout;
using std::endl;

int test (void);

int main (void){

    //if((auto k = test()) != 0){
    if(auto k = test()){
        cout << "odd" << endl;
    }
    else{
        cout << "even" << endl;
    }

    return 0;
}

int test (void){
    static auto invocation_count = -1;
    ++invocation_count;
    return(invocation_count % 2);
}

But if the if condition is to be substituted by the line above (commented out), the following compilation errors ensue:

g++ -ggdb -std=c++17 -Wall -Werror=pedantic -Wextra  -c code.cpp
code.cpp: In function ‘int main()’:
code.cpp:9:9: error: expected primary-expression before ‘auto’
     if((auto k = test()) != 0){
         ^~~~
code.cpp:9:9: error: expected ‘)’ before ‘auto’
code.cpp:13:5: error: expected ‘)’ before ‘else’
     else{
     ^~~~
code.cpp:17:13: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body]
     return 0;
             ^
make: *** [makefile:20: code.o] Error 1

Aren't the two if condition statements technically the same? Why is it that one compiles where as the other doesn't?

Vinod
  • 925
  • 8
  • 9
  • 2
    The accepted answer of the post you linked to explains why `(auto k = test())` is not a valid expression. – R Sahu Sep 25 '19 at 04:57
  • 3
    `(auto k = test()) != 0` is not a declaration and not an expression. It is a syntax error. – n. m. could be an AI Sep 25 '19 at 04:58
  • @n.m.could you please point out the syntax error? I thought it was valid syntax to do the assignment within brackets as the != operator has higher precedence. – Vinod Sep 25 '19 at 05:01
  • @Macmade no it is not a duplicate of that post. That post is what I have referred to in my post. – Vinod Sep 25 '19 at 05:03
  • @RSahu the accepted answer in the referred to post mentions that in the context of ternary operator, not if statement condition. In fact, it specifically says that it is perfectly valid to include declaration inside if condition. – Vinod Sep 25 '19 at 05:05
  • 2
    It is a duplicate, because the answer on that question has all the information needed to understand why `if((auto k = test()) != 0)` is not valid. – Max Vollmer Sep 25 '19 at 05:05
  • Yes, you can use a declaration inside the if-condition. `if(auto k = test())` is perfectly fine. `(auto k = test()) != 0` is not a declaration. – Max Vollmer Sep 25 '19 at 05:06
  • 2
    `auto k = test()` is not an assignment. – n. m. could be an AI Sep 25 '19 at 05:06
  • @Vinod, it's not clear to me what you are hoping to get if the answer from the other post doesn't give you an answer. – R Sahu Sep 25 '19 at 05:14
  • @Macmade From the accepted answer, I can infer that using declaration inside the if condition is valid C++, whereas using declaration on the lhs of ? of a ternary operator is not. Even if comparison with 0 as in != 0 inside the if condition is not a declaration and an expression, shouldn't that work? isn't it valid C++ to use an expression inside the if condition? – Vinod Sep 25 '19 at 05:14
  • It looks like you infer that "using declaration **anywhere** inside the if condition is valid C++". This is not correct. – n. m. could be an AI Sep 25 '19 at 05:25
  • @n.m.would appreciate if you or someone else could comment on what is allowed and not allowed with respect to declaration inside if condition. – Vinod Sep 25 '19 at 05:27
  • 1
    There are exactly two things that are allowed as an if condition. (1) a declaration (2) an expression. What do you think `(auto k = test()) != 0` is, a declaration or an expression? Please note that (3) something that looks a bit like a declaration and a bit like an expression is not a valid option. Also note that although `auto k = test()` is a declaration, it is not an if condition in your example. – n. m. could be an AI Sep 25 '19 at 05:34
  • 1
    You seem to miss that `(auto k = test()) != 0` in itself is invalid. This has nothing to do with it being inside an if-condition or not. `(auto k = test()) != 0` simply is not valid C++. To make it simpler, just add `(int i = 0) != 0;` anywhere in your code and see what your compiler tells you. – Max Vollmer Sep 25 '19 at 05:37
  • Since C++17, there's a variant of `if` that allows to do what you want, though (and it's even used in referenced question): `if(auto k = test(); k != 0)`. – Aconcagua Sep 25 '19 at 05:37
  • @Vinod `auto k = test()` is a declaration (with initialiser). You cannot use as argument for ternary operator (as in referenced question), but you cannot *either* as operand for `operator !=`. – Aconcagua Sep 25 '19 at 05:48
  • Some elaboration why I think the duplicate is justified: The answer in the dupe states that it's valid to have a declaration inside an if-condition. Note: *a declaration*, not *an expression that contains a declaration*. It then continues and explains that declarations are not valid in many places where expressions are valid, giving as *one example* the ternary operator. From that it is easy to deduce that using a declaration with the != operator is not valid either. Since OPs question is primarily about the former and less about the latter, the duplicate answers it sufficiently. – Max Vollmer Sep 25 '19 at 05:50
  • @MaxVollmer *'There are places where expressions are allowed, but declararions are not.'* is the key in referenced answer. *'Easy to deduce'* for experienced people like us, sure, but apparently not that easy for beginners. That's why all that discussion here has arisen. – Aconcagua Sep 25 '19 at 05:57
  • Maybe, but I don't think it's justified to have a separate question and answer simply for *"oh btw, != is also not allowed"*. If anything, it may be adressed in the duplicate, not here. But honestly, with that reasoning we'd have to create a complete list of all the places where declarations are (not) allowed - and if someone asked for that, I'd agree that it's not a duplicate (of that particular question). But that's not what OP asked. – Max Vollmer Sep 25 '19 at 06:03
  • @MaxVollmer I agree with the observation of Aconcagua, Aconcagua's answer finally made it clear to me what was the root cause of the error. I also would like to concur with Aconcagua's more grounded observation that it might not be possible for everyone to make that deduction based on the answer provided to the original post. – Vinod Sep 25 '19 at 06:36
  • @MaxVollmer I actually can agree on the duplicate, however, all this discussion proves that *'that question has all the information needed to understand'* obviously does not suffice to explain why, we would have needed the *'oh btw'* right there (not intended as criticism, just as conclusion what we all can learn from here). – Aconcagua Sep 27 '19 at 06:00

0 Answers0