下面的代码会被优化为一个函数调用吗
Would the following code be optimized to one function call?
我几乎没有编译器专业知识,我想知道以下代码片段是否会被相对较新的(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()只是返回一个成员变量,该变量是枚举中的一个。(呼叫没有明显影响)
我的编码风格是在"switch"之前进行一次调用,并保存值以将其与每个somethingX进行比较,但我想知道这对于今天的编译器来说是否是一个没有意义的问题。
我自己也不确定该用谷歌搜索什么来找到答案。
谢谢你,
AK
这是没有实际意义的,尤其是在方法是可变的情况下。
如果未声明getValue
为const
,则无法优化该调用,因为后续调用可能返回不同的值。
如果它被声明为const
,它会更容易,但编译器优化调用也很简单。它需要访问实现,以确保调用不会产生副作用。即使标记为const
(修改并返回全局),它也有可能返回不同的值。
除非编译器能够在编译该段代码时检查getValue()
的定义,否则它不能省略第二次调用,因为它不知道该调用是否具有可观察的效果,也不知道第二次是否返回相同的值。
即使它看到了定义,它也很可能(这是我对一些编译器内部的粗略猜测)不会特意检查这一点。唯一的可能性是实现被琐碎的和内联两次,然后被公共子表达式消除捕获EDIT:由于定义在标头中,而且非常小,所以这(内联和随后的CSE)很可能会出错。不过,如果您想确定,请检查g++ -O2 -S
或编译器的等效输出。
总之,您不应该期望优化发生。再说一遍,getValue
可能相当便宜,所以不太可能值得手动优化。与几个机器循环相比,额外的一行是什么?在大多数情况下不多。如果您正在编写代码,那么您不应该询问,而应该检查它(反汇编/分析)。
正如其他答案所指出的,编译器通常无法消除第二个调用,因为可能会有副作用。
然而,有些编译器有一种方法可以告诉编译器该函数没有副作用,并且允许进行这种优化。在GCC中,函数可以声明为pure。例如:
int square(int) __attribute__((pure));
表示,该函数"除了返回值之外没有任何效果,并且返回值仅取决于参数和/或全局变量。">
您写道:
我的编码风格是在"切换"之前进行一次调用,并保存值以进行比较它反对X的每一个,但我想知道这是否是一个没有意义的观点使用今天的编译器。
是的,这是一个没有意义的问题。编译器所做的就是它的业务。你将忙于编写可维护的代码,而不必试图对一个比我们任何人都希望的工作都要好得多的软件进行微观管理
专注于编写可维护的代码,并相信编译器能够完成任务。如果你以后发现你的代码太慢,那么你可以担心优化。
记住这句谚语:
过早的优化是万恶之源。
- 使用另一个函数调用一个函数(都在类中)时出现问题.没有错误代码C++
- 重载运算符主体仅包含一个函数调用
- 在 MySQL 连接器C++ API 中使用一个函数调用执行多个查询的正确方法是什么?
- C++编译器在一个源文件中的一个函数调用中引发错误,但在具有相同函数调用的另一个源文件中不会引发错误
- while 循环在一个函数调用中执行两次
- 在C++中嵌入Python:在Python脚本中导入模块在一个函数调用过程中有效,但在另一个调用过程中无效
- 如何从前面定义的另一个函数调用函数模板
- 下面的代码会被优化为一个函数调用吗
- C++中的神秘:函数调用行为不端只是因为存在另一个函数调用,即使它们是不相关的
- 我可以静态地阻止一个函数调用另一个函数吗
- c++oop初学者-在一个函数调用中返回向量中每个创建对象的输出和
- 如何告诉编译器向编译的每个函数添加一个函数调用
- 存储一个函数的迭代结果,并在被另一个函数调用时使用它们
- 在一个函数调用中创建线程池,并从另一个函数调用来使用它
- 如何使用谷歌测试零或一个函数调用进行检查
- 一个函数调用另一个函数时使用的内存会发生什么情况
- 从一个函数调用另一个函数
- 只需一个函数调用即可输出分数
- 在C/ c++中,当两个函数具有相同的名称,一个函数调用另一个函数时,它将工作
- 为什么arduino忽略了一个函数调用