c - if 语句、函数评估和编译器优化
问题描述
只是一个简单的问题,以使我免于测试(尽管我确实应该测试以绝对确定):
给定以下 C 代码:
r1 = fun1();
r2 = fun2();
if (r1 && r2)
{
// do something
}
变量r1
并且r2
没有在代码中的任何其他地方使用,除了在if (...)
语句中。是否会评估这两个功能?我担心编译器可能会通过消除r1
and来优化代码r2
,从而使它看起来像这样:
if (fun1() && fun2())
{
// do something
}
在这种情况下,fun1()
将首先评估,如果它返回FALSE
,则fun2()
根本不会评估。这不是我想要的,这就是我在第一个代码段中对其进行编码的原因。
如何保证始终评估函数?我认为这可以通过将它分配给一个变量来完成,但是如果它发现这个变量以后实际上从未在代码中使用过,我会担心编译器优化......
我知道这可以通过声明r1
and r2
as来实现volatile
,但我想知道是否有更优雅的解决方案。
非常感谢您对此问题的任何评论,谢谢!
编辑:感谢所有回答的人。我刚刚在我的项目中使用了我的第一个代码片段(它是一个基于 ARM Cortex-M7 的嵌入式系统)。似乎编译器没有按照我上面展示的方式优化代码,并且两者都 被评估(因为它们应该)。此外,使用和声明为编译代码会产生与 when和只是普通变量完全相同的二进制输出(即,关键字根本不会改变编译器输出)。这让我放心,第一个代码片段实际上是在处理后面的语句之前评估这两个函数的有保证的方法。fun1()
fun2()
r1
r2
volatile
r1
r2
volatile
if (...)
解决方案
假设代码没有表现出任何未定义的行为,编译器只能执行与未优化代码具有相同外部可见行为的优化。
在您的示例中,这两段代码做了两件不同的事情。具体来说,一个总是调用fun2
,而另一个有条件地调用它。所以你不必担心第一段代码会做错事。
推荐阅读
- php - Apache 挂起 200 秒后未收到输出
- javascript - (Tizen Web App)获取地理位置不能解决模拟器中的错误或成功
- apache-spark - Spark中的执行器超时错误
- python - mongodb如何保存注册用户数?
- c# - C# UDP 套接字的 ReceiveBufferSize 是否适用于数据报的大小或消息队列的大小?
- c# - MVC无法上传文件
- java - Keycloak:订阅诸如创建用户之类的事件以触发 Web 服务
- sql - 将一个表中的值与另一表中具有相同属性的值的平均值计算进行比较
- utf-8 - UTF-8 直接存储代码点的基本原理是什么?
- javascript - 防止在完全填充之前渲染 fabric-js 画布