现代编译器会自动优化以下C ++代码吗?

时间:2012-02-20 10:06:08

标签: c++ if-statement g++

如果我使用hte以下代码,编译器是否会像开关结构一样优化它,它使用二叉树来搜索值?

   if ( X == "aaaa" || X == "bbbb" || X == "cccc" || X == "dddd" )
   {

   }
   else if ( X == "abcd" || X == "cdef" || X == "qqqq" )
   {

   }

这只是一个例子,引号中没有什么模式

更新

好的,X是一个字符串,但我认为这并不重要,我只是想知道,当if内的所有内容都是关于单个变量的时候,它会被优化。

4 个答案:

答案 0 :(得分:3)

这些值将一个接一个地进行比较,因为它是||或短路运算符的要求。所以,这里会发生两件事:

  • X将从右到左逐一进行比较。
  • 在任何成功的比较之后将没有更多的比较(因为它是短路OR运算符),即在以下情况中

例如:

int hello() {
    std::cout<<"Hello";
    return 10;
}

int world() {
    std::cout<<"World";
    return 11;
}

int hello2() {
    std::cout<<"Hello2";
    return 9;
}

int a = 10;

bool dec = (a == hello() || a == world())
bool dec = (a == hello2() || a == hello() || a == world())

第一个语句的输出将是:

Hello

因为a == world()将不会被执行,而第二个Hello2 Hello将被执行,因为比较会一直持续到第一次成功。

对于&&运算符,比较会一直发生,直到第一次失败(因为这足以确定整个语句的结果)。

答案 1 :(得分:1)

这可能取决于您设置的标志。二叉树搜索速度更快,但通常需要处理更多代码。所以,如果你针对尺寸进行优化,它可能不会。我不确定它是否会这样做。你知道,gcc根据很多标志进行了优化。 O1,O2,O3,O4只是表示大组标志的简单形式。您可以在此处找到所有优化标记的列表:http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

尝试在该页面中搜索字符串,二叉树等。

答案 2 :(得分:1)

几乎肯定不是。二进制搜索需要某种排序 关系,以及比较少于的关系的能力。编译器 不能假设这样存在,即使它找到了一个,它也不能 假设它定义了一个对应的等价关系 ==。也有可能编译器无法确定 定义排序关系的函数没有副作用。 (如果它 有副作用,或表达式中的任何操作有副作用 效果,编译器必须尊重短路行为 ||。)最后,即使编译器做了所有这些......如果我发生了什么 仔细选择比较顺序,以便最频繁 案件是第一个。这种“优化”甚至可能最终结束 是一种悲观情绪。

处理这个的“正确”是创建一个映射,映射 字符串指向函数(或多态函数对象, 如果涉及某个州)。

答案 3 :(得分:0)

测试此方法的最佳方法如下所示。

int a = 0;
int b = 0;
if(a == a || b++) {
    ...
}
cout << b;

b变量的值最后应为0b++部分将不会被执行。这是预期的行为,但可能会有一些例外情况,具体取决于编译器及其优化设置。甚至像JavaScript这样的脚本语言也是这样的。