简体   繁体   中英

Compound expression in if statement

I stumbled upon the ability to do this.

#include <iostream>
using namespace std;

int main() {
    if ( ({int i = 1024; i == 10;}) ) {
        cout << "In" << endl;
    }
}

The important disassembly area seems to be:

->  0x10000118f <+15>: movl   $0x400, -0x18(%rbp)       ; imm = 0x400 
    0x100001196 <+22>: cmpl   $0xa, -0x18(%rbp)
    0x10000119a <+26>: sete   %al
    0x10000119d <+29>: andb   $0x1, %al
    0x10000119f <+31>: movb   %al, -0x19(%rbp)
    0x1000011a2 <+34>: testb  $0x1, -0x19(%rbp)
    0x1000011a6 <+38>: je     0x1000011d9               ; <+89> at main.cpp:37

From examining this, it does seem like it takes the last statement (the comparison i == 10 ) as the boolean for the if statement.

I understand that this case doesn't allow me to use variable i within the if statement because of the scope operator, but wanted to know why the if statement decides to use i == 10 as the boolean statement.

For alternatives to this, I understand that a function call might be cleaner which returns a boolean that I can use to set to a variable for the if statement. However, I see MACROs that expand to this very similar style within glibc source code.

Is it an old style of programming with MACROs?

Is there a benefit to this I am missing?

A GCC extension to the C++ language allows a parenthesized compound statement (that is, semicolon-delimited statements, inside braces, inside parentheses) to be used as an expression. To evaluate the expression, the statements are executed in order, and the value of the expression in the last statement is used as the value of the expression as a whole.

It's primarily useful for function-like macros which need to declare local variables of their own. Because it's GCC-specific, it's best to avoid it unless absolutely necessary — and in the case of C++, function-like macros themselves are best avoided, in favor of template functions.

So it's a nice thing to know about, but it's not a good thing to use in C++, even on a compiler which supports it.

EDIT: As Jodocus noted, there's a similar feature available in C++17, whereby a for-loop-style initializer can precede the condition in an if-statement (as it does in a for-statement). Personally I think it's an unnecessary complication, as it has roughly the same effect as just putting the initializer and the if-statement in braces, but in the code you posted it would technically be a valid option.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM