【问题标题】:Why can't compilers suggest const for me?为什么编译器不能为我建议 const ?
【发布时间】:2016-05-10 20:51:01
【问题描述】:

取下面的sn-ps代码:

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';
}

编译器肯定会为我提出建议吗?
查看clanggcc,我没有看到任何相关标志。

编译器选择不提供这个有什么原因吗?

【问题讨论】:

  • 您可能喜欢真正的函数式语言,其中所有变量都是不可变的。
  • int Add(const int x, const int y)const int i = 5; 是蹩脚的 IMO。仅将成员函数标记为const 很重要。
  • @SergeyA:它们不是真正的“变量”,那么它们不是
  • @M.M:我完全不同意。
  • @LightnessRacesinOrbit:我很确定你可以不同意更多(但是是的 - const ftw!)

标签: c++ g++ constants compiler-warnings clang++


【解决方案1】:

因为他们往往会弄错。

你可以说这样做对文件静态类文件静态函数有好处,因为编译器可以看到这些项目的所有使用在单个编译单元中(这是这种事情的先决条件)。但是你有几个?

花费大量时间将这种能力编程到编译器中根本没有任何好处,而收益如此之小。尤其是当您已经有代码审查来代替时。

不过,专业的静态代码分析工具可能具有此功能。货比三家。

【讨论】:

  • 我偶尔会考虑反转语义的想法 - 除非声明 nonconst,否则一切都是 const。
  • @SergeyA:我非常希望 constmutable 的语义可以颠倒过来。
  • 作为rust,其中mut 是可变的(而没有mut 的东西是const)并建议删除不需要的mut。 :-)
【解决方案2】:

编译器选择不提供这个有什么原因吗?

它的部分历史(虽然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;
}

两者之间有区别(尽管在 codegen 中没有)...您可以在后者中重新分配变量,但不能在前者中重新分配:看,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 在您可以将内存位置标记为只读的系统中非常重要。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-01
    • 1970-01-01
    • 2020-07-23
    • 2012-02-23
    相关资源
    最近更新 更多