if语句中的复合表达式

时间:2018-05-15 14:57:50

标签: c++ if-statement gcc

我偶然发现了这样做的能力。

#include <iostream>
using namespace std;

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

重要的反汇编区域似乎是:

->  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

通过检查,看起来它似乎需要最后一个语句(比较i == 10)作为if语句的布尔值。

我理解这个案例不允许我在if语句中使用变量i,因为范围运算符,但想知道 if语句决定的原因使用i == 10作为布尔语句。

对于替代方案,我理解函数调用可能更干净,它返回一个布尔值,我可以用它来设置if语句的变量。但是,我看到MACRO在glibc源代码中扩展为非常相似的样式。

这是一种旧式的MACRO编程方式吗?

我遗失了这个有益处吗?

1 个答案:

答案 0 :(得分:6)

C ++语言的GCC扩展允许使用带括号的复合语句(即以括号分隔的括号中的分号分隔语句)作为表达式。要计算表达式,语句按顺序执行,最后一个语句中表达式的值作为整个表达式的值使用。

它主要用于类似函数的宏,它需要声明自己的局部变量。因为它是GCC特有的,除非绝对必要,否则最好避免它 - 在C ++的情况下,最好避免使用类似函数的宏,而不是模板函数。

所以要了解它是一件好事,但在C ++中使用它并不是一件好事,即使在支持它的编译器上也是如此。

编辑:正如Jodocus所指出的那样,C ++ 17中提供了类似的功能,其中for循环样式的初始化程序可以在if语句中的条件之前(就像在for语句中一样) 。我个人认为这是一个不必要的复杂问题,因为它与将初始化程序和if语句放在大括号中具有大致相同的效果,但在你发布的代码中它在技术上是一个有效的选项。