获取以下代码片段:
struct Foo{
int _m=0;
int Bar(){
return _m;
}
};
int Add(int x, int y){
return x + y;
}
int main(){
int i = 5;
std::cout << i << '\n';
}
在代码审核过程中,有人会不可避免地提出const correctness 这导致以下修订:
struct Foo{
int _m=0;
int Bar() const{
return _m;
}
};
int Add(const int x, const int y){
return x + y;
}
int main(){
const int i = 5;
std::cout << i << '\n';
}
当然,编译器可以为我建议吗?
查看clang
和gcc
,我看不到任何相关标记。
编译器是否选择不提供此功能?
答案 0 :(得分:1)
因为他们往往错了。
你可以说这对于文件 - 静态类和文件 - 静态函数这样做是有好处的,因为编译器可以看到这些项的所有用法在一个单独的编译单元(这是这种事情的先决条件)。但是你有多少人?
将这种能力编程到编译器中需要花费大量时间才能获得这样的最小增益。特别是当您已经进行代码审查时,不会这样做。
专业的静态代码分析工具可能具有此功能。到处逛逛。
答案 1 :(得分:0)
编译器是否选择不提供此功能?
部分历史性(尽管Rust试图address this问题);至于为什么默认情况下它不应该是const
:在高级别上,编译器可能不像你想象的那样了解你的意图; (假设,在解析文件的阶段,它确定您没有修改变量(即:它可能是const
):执行constness
的问题将基本消失在那个阶段)。原因是,这些详细信息couldBeSafelyAssumedConst
可能对优化程序有所帮助。
考虑:
int Add(const int x, const int y){
return x + y;
}
和
int Add(int x, int y){
return x + y;
}
这两者之间存在差异(虽然不是代码生成)...你可以在后者中重新分配变量而不是前者:看看,const
的使用在很大程度上是你的职责,具体到你的意图/目的/合同等......
同样,除了提供更多优化机会之外,const
在很大程度上阻止了程序员的意外修改。当编译器生成本机代码时,没有const
正确性 * 的任何概念:
示例:https://godbolt.org/g/Blpmpu ...(转载于此处):
struct Foo{
int _m=0;
int Bar(){
return _m;
}
};
int foo(const Foo& fg){
Foo f(fg);
int q = f.Bar() *4;
return q;
}
为此生成的代码是:
foo(Foo const&):
movl (%rdi), %eax
sall $2, %eax
ret
如您所见,codegen 并非了解const-correctness
。 我认为编译器的工作是编译代码。你的工作(在其他工具的帮助下)可以正确地记录你的意图(从各个方面)。
* 原因是const
在您可以将内存位置标记为只读的系统中非常重要。