首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么优化器不优化这段代码?

为什么优化器不优化这段代码?
EN

Stack Overflow用户
提问于 2022-03-16 08:18:33
回答 2查看 68关注 0票数 0

使用最大优化设置编译和运行此代码似乎会产生相同的结果。

代码语言:javascript
复制
#include <stdio.h>

class A
{
public:
    A() { }
    const int* begin() const { return a; };
    const int* end() const { printf("end\n"); return a + 3; };
    bool isTrue() const { return true; }
    int a[4];
};

const A a{};

class B
{
public:
  const A& operator[](size_t) const { printf("B called\n"); return a; }
};


int main()
{
    const B b{};
    if (!b[0].isTrue()) return -1;
    for (const auto& x : b[0]) printf("%d\n", x);
}

我对B类型的常量对象调用b两次,operator[]返回A类型的常量对象。

为什么"B叫“被印了两次?为什么代码不能将b保存在一边,并在其上运行不同的功能?(由于这些函数是const函数,它们将返回相同的结果.)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-03-16 08:23:00

为什么"B叫“会被打印两次?

首先,因为您在main中引用了两次b[0]。而且因为操作符函数中的printf语句指示访问b[0]有副作用。所以编译器不能假设您的printf仅用于调试-它必须对每个调用调用一次。

如果我们删除printf语句并进行计算,就可以看到代码经过了很大的优化,可以在没有任何调用的情况下打印0三次。

优化:https://godbolt.org/z/E8czPdr5W

票数 3
EN

Stack Overflow用户

发布于 2022-03-16 08:24:05

operator[]和其他函数一样是一个正常的函数,因为C++没有纯函数的概念,所以编译器必须假定每个函数都有副作用。一个这样的副作用是您的printf调用。如果您优化了对operator[]的一个调用,您的程序行为可能会改变(在这里,它只打印一次而不是两次)。想象一下,您将调用数据库或其他重要的东西而不是printf。如果只是经过优化,那就太糟糕了。

还请注意,const成员函数与纯函数并不相同。const意味着它不能修改调用成员函数的实例,但是仍然可以更改全局变量。您甚至无法保证const成员函数不会更改实例的状态,因为您可以在特定条件下丢弃const

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71493678

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档