2016-05-10 12 views
1

は、次のコードスニペットを取る:なぜコンパイラがconstを提案できないのですか?

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を見ると、関連するフラグはありません。

コンパイラがこれを提供しない理由がありますか?

+1

すべての変数が不変の真の関数型言語が好きかもしれません。 – SergeyA

+0

'int(const int x、const int y)'と 'const int i = 5;'は不完全なIMOです。メンバ関数を 'const'としてマークすることだけが重要です。 –

+0

@ SergeyA:彼らは本当に "変数"ではありません。 –

答えて

1

これは間違っている可能性が高いためです。

その後、それらの項目のすべての使用は、単一のコンパイル単位(にコンパイラに表示されているので、あなたは、ファイル静的クラスファイル・スタティック関数のためにそうすることで利益があると主張することができこの種のものの前提条件)。しかし、あなたはどれくらい持っていますか?

最小限の利益のために、この能力をコンパイラにプログラムするのに多大な時間を費やすだけの利点はありません。特に、コードレビューを既にお持ちの場合は特にそうではありません。

しかし、プロフェッショナルなスタティックコード解析ツールにはこの機能が搭載されている可能性があります。ショップ周辺。

+0

私はときどき反転セマンティクスの考え方を楽しんでいます - すべてが非constと宣言されていない限りconstです。 – SergeyA

+3

@SergeyA:私は 'const'と' mutable'の意味が逆転したかったことを大いに願っています。 –

+0

[tag:rust]として、mutableにmutがあります(mutがないものはconst)ので、不要なmutの削除を提案します。 :-) – Jarod42

0

コンパイラがこれを提供しない理由がありますか?

その部分的に歴史的です(ただし、Rustaddress 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; 
} 

を2つ(ないコード生成にかかわらず)との差があります...あなたは後者の前者ないで変数を再割り当てすることができます:参照してください、constの使用は主にあなたの義務であり、あなたの意図/目的/契約などに特有です...


ここでも、離れてより多くの最適化の機会を提供するから、constは主に不慮の変更からプログラマを防ぐことができます。

例:https://godbolt.org/g/Blpmpu ...(ここでは再現):コンパイラはネイティブコードを生成する場合、const正し*のいずれかの概念がない

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は読み取り専用として使用すると、メモリ位置をマークすることができますシステムで非常に重要です。

関連する問題