2017-02-16 42 views
1

我有一个C++类是这样的:编译器能否优化掉方法调用?

class MyClass { 
    int calculate(int arg1) const; 
    void side_effect(int arg) const; 
} 

这是用这样的:

{ 
    MyClass m; 
    m.calculate(100); 
    m.side_effect(100); 
} 

是编译器的自由跳过m.calculate()电话 - 因为我不坚持到返回值?对于side_effect()方法,我真的希望编译器不能跳过这个调用 - 即使这个方法被标记为const

编辑:我问这个问题的原因是我的calculate()函数有副作用,但通过使用mutable它被标记为const。现在,在正常情况下,我想坚持返回值,整个问题都没有实际意义 - 但在上面的例子中,我只关心确定副作用已被调用(是的 - 我知道它不是漂亮 ...)。阅读答案/评论我感觉你认为编译器可以推断出一种方法是否有副作用;这令我感到惊讶?

+2

结果必须是 - 如果函数被调用。如果它没有效果,你怎么能说出不同? –

回答

5

这取决于m.calculate()做什么。

如果它只是检索值然后将它们丢弃,那么确实没有什么用处可以让您的计算机在此处执行,而且您的完成的程序甚至可能甚至无法拨打电话。

但是,编译器可以执行优化的程度受限于函数定义的可见性以及其他因素。

const与它无关。所以,如果m.side_effect()有副作用,它不能被跳过。

0

编译会优化掉任何在运行时没有效果的代码,如果它可以告诉编译时,永远不会调用的分支和永远不会使用的值。 Const数据和对象在这里很方便,因为它们的值在编译时是已知的。将const放在方法上本身不会改变:它只是意味着你知道这个方法不会改变它的对象。对象本身仍然是非const的,所以即使方法是const,编译也不会100%知道该方法运行时数据值可能是什么。非const方法仍有可能在某个时刻改变了对象。

此外,在类中声明的方法是内联的:它们将被代码本身替代,而不是函数调用。无论side_effect方法做了什么“动作”,都会直接写入代码中,代替函数调用本身。整个事情不会被优化,除非它实际上什么都不做,这应该不成问题。

顺便说一句。 const方法仍然可以影响相关的对象,例如通过类内的指针访问数据,它可以自由地改变指向的数据,但不能改变指针本身的地址。

+1

“它们将被代码本身替代,而不是函数调用”。他们**可能被代码替换。我听说没有编译器会肯定内联inline方法。它将决定编译过程中哪些更好。 – riodoro1

0

让我们区分'can'和'should'应该更多地presize。 关于'can',compiller优化某些cetain代码结构的能力取决于代码设计以及编译器的“智能”程度。随着编译器的更多提示,可以更紧密地优化某些内容。

在你的情况下,如果功能side_effectcalculate是假的,并没有做任何事情(和calculate返回静态硬编码值),它们可以被优化掉。除此之外,它们的参数也可以在它们被声明和定义的地方进行优化(请不要将这种情况与“应该”混合)。但是由于这个原因(特别是如果使用了一些简单的Compiller),您可能需要提供更多关于将参数声明为int的参数的提示,而不是通过值传递它们。

在这种情况下,你的代码

MyClass m; 
m.calculate(100); 
m.side_effect(100); 

不会产生可执行既不功能,也没有为他们的参数的任何指令。另外,给const,你不会强制compiller去优化某些代码,但是你可以帮助编译器认识到代码在优化时可以被优化。