以下代码是否会针对一个函数调用进行优化?

时间:2012-12-06 19:35:38

标签: c++ compiler-optimization

我很少(读不)编译器专业知识,并且想知道以下代码片段是否会被相对较新的(VS2008 + / GCC 4.3+)编译器自动优化:

Object objectPtr = getPtrSomehow();

if (objectPtr->getValue() == something1)       // call 1
    dosomething1;
else if (objectPtr->getValue() == something2)  // call N (there are a few more)
    dosomething2;

return;

其中getValue()只返回一个成员变量,它是枚举之一。 (电话没有可观察到的影响)

我的编码风格是在“切换”之前进行一次调用并保存值以将其与每个事物X进行比较,但我想知道这是否与今天的编译器有关。

我也不确定谷歌应该自己找到答案。

谢谢,

AK

4 个答案:

答案 0 :(得分:4)

这不是没有实际意义,特别是如果方法是可变的。

如果getValue未声明为const,则无法优化呼叫,因为后续呼叫可能会返回不同的值。

如果声明为const,那么编译器优化呼叫会更容易,但也非常简单。它需要访问实现,以确保调用没有副作用。即使标记为const(修改并返回全局),它也有可能返回不同的值。

答案 1 :(得分:3)

除非编译器在编译该段代码时可以检查getValue()的定义,否则它不能忽略第二次调用,因为它不知道该调用是否具有可观察的效果以及它是否返回相同的第二次重视。

即使它看到了定义,它可能是(这是我对一些编译器内部的一些看法的疯狂猜测)也不会用它来检查它。你唯一的机会就是实现是微不足道的内联两次,然后然后被公共子表达式消除所捕获。 编辑:由于定义位于标题中,并且非常小,因此可能会出现这种情况(内联和后续的CSE)。不过,如果你想确定,请检查g++ -O2 -S或编译器等效的输出。

总而言之,您不应该期望进行优化。然后,getValue可能相当便宜,因此不太可能值得进行手动优化。与几个机器周期相比,什么是额外的线?在大多数情况下,并不多。如果你在很多的地方编写代码,你不应该只是检查它(反汇编/分析)。

答案 2 :(得分:2)

正如其他答案所指出的那样,编译器通常无法消除第二次调用,因为可能存在副作用。

然而,一些编译器有一种方法告诉编译器该函数没有副作用,并且允许这种优化。在GCC中,函数可以声明为。例如:

int square(int) __attribute__((pure));

表示该函数“除了返回值之外没有任何效果,[返回值]仅取决于参数和/或全局变量。”

答案 3 :(得分:1)

您写道:

  

我的编码风格是在“切换”之前拨打一个电话并保存值进行比较   它反对每一个X的东西,但我想知道这是不是一个有争议的问题   今天的编译器。

是的,这是一个有争议的问题。编译器的作用是它的业务。你的双手将尽力编写可维护的代码,而不是试图微观管理一个比我们任何人都希望的更好的软件。

专注于编写可维护代码并信任编译器来执行其任务。如果您以后发现代码太慢,那么您可以担心优化。

记住这句谚语:

  

过早优化是万恶之源。