c++ - c++:有没有办法确保编译器调用两次相同的 const 方法得到相同的结果?
问题描述
我对以下两个简单的片段感到困惑:
#include <vector>
struct A{
int foo(int i) const {return v[i];}
std::vector<int> v;
};
int f(const A &a, int i) {
int j;
j=a.foo(i);
j=a.foo(i);
return j;
}
它给出了汇编代码:
movsxd rax, esi
mov rcx, qword ptr [rdi]
mov eax, dword ptr [rcx + 4*rax]
ret
和
#include <vector>
struct A{
int foo(int i) const;
std::vector<int> v;
};
int f(const A &a, int i) {
int j;
j=a.foo(i);
j=a.foo(i);
return j;
}
这使:
push rbp
push rbx
push rax
mov ebp, esi
mov rbx, rdi
call _ZNK1A3fooEi
mov rdi, rbx
mov esi, ebp
add rsp, 8
pop rbx
pop rbp
jmp _ZNK1A3fooEi # TAILCALL
在第一种情况下,编译器“看到”函数的内部,foo
并知道他不必调用它两次。在第二种情况下,它只有它的声明,它似乎不能假设它只能调用一次函数,而函数是 const ......为什么会这样?这是i
函数内部和函数之间的别名问题foo
吗?如果这是一个别名问题,我如何确保编译器不担心这个问题?
解决方案
成员函数是const
-qualified 的事实并不意味着该函数没有任何副作用。在没有看到函数定义的情况下,编译器无法确定该函数不会将某些内容输出到文件中,也不会通过网络发送某些内容等。因此,通常,仅调用一次相同的成员函数可能不会产生等效的结果调用它两次(尽管函数被const
-qualified)。
编辑:回答最初的问题:目前,没有标准方法可以将函数标记为没有副作用。一些编译器可能支持自定义属性,例如[[gnu::pure]]
and [[gnu::const]]
,但这不是标准的。
推荐阅读
- spring - 在 Spring 中订购自动连线列表 - 低于最低优先级
- python - 在数据库中查找值
- java - @Autowired 对于具有 @InjectMocks 注释的测试中的 bean 是多余的吗?
- java - 仅对实际上是被覆盖类型的键使用自定义键序列化程序
- flutter - 如何为嵌套模型制作不同的表加入它们,而不是使用 sqflite 将它们展平或更改为 json 或字符串?
- django - Django Bootstrap模式更新表单不显示数据
- javascript - Gitlab和赛普拉斯-加载共享库时出错:libxshmfence.so.1:无法打开共享对象文件:没有这样的文件或目录
- python - 如何编写一个 python 程序,打印出所有至少三个字符长的子字符串?
- r - 有向图的 eigen_centrality (R)
- google-cloud-platform - GoogleAPICallError:无意外状态:长时间运行的操作既没有响应也没有错误集