staticキーワードの廃止…これ以上?


89

C ++ではstatic、変換ユニット内でキーワードを使用して、シンボル(変数または関数宣言)の可視性に影響を与えることができます。

n3092では、これは非推奨になりました。

付録D.2 [depr.static]
名前空間スコープでオブジェクトを宣言する場合、staticキーワードの使用は非推奨になりました(3.3.6を参照)。

n3225では、これは削除されました。

私は見つけることができる唯一の記事は、やや非公式です。

ただし、Cとの互換性(およびCプログラムをC ++としてコンパイルする機能)のために、非推奨は煩わしいことを強調しています。ただし、CプログラムをC ++として直接コンパイルすることは、すでに苛立たしい経験になる可能性があるため、検討する必要があるかどうかはわかりません。

なぜ変更されたのか誰か知っていますか?


3
Cの名前空間スコープでオブジェクトを宣言しますか?
エティエンヌデマルテル2011年

heh、thx、どこでそれを手に入れるかを見つけました。コメントを削除しようとしましたが、あなたはそこで私を打ち負かしました。
エドワードストレンジ


1
これにより、C ++委員会は、標準の次のバージョンで何かを非難する機会も得られます:-)
James McNellis 2011

回答:


75

ではC ++標準のコア言語不具合レポートと認められた問題、リビジョン94の下で1012 Undeprecatingの静的`彼らは注意してください。

7.3.1.1 [namespace.unnamed]は、名前空間スコープで変数を宣言するためのstaticキーワードの使用は、名前空間が優れた代替手段を提供するため非推奨であると述べていますが、近い将来、この機能が削除される可能性はほとんどありません。 。

基本的に、の非推奨はstatic実際には意味がないと言っています。C ++から削除されることはなく、内部リンケージを使用して関数またはオブジェクトを宣言するだけの場合は、名前のない名前空間で必要な定型コードが必要ないため、引き続き役立ちます。


2
そうですね、非推奨になると、代わりに名前のない名前空間を使用するようになります。これは良いことです。
sbi 2011

1
@unaperson:他の理由がない場合、名前のない名前空間は、変数、定数、関数、および型をTUの内部に作成するための同じメカニズムを提供するためです。static class ... 、OTOH、動作しません。
sbi 2011

2
@nbt:静的シンボルをテンプレート引数として使用することはできず、多くの初心者は静的が使いやすいと感じ、<functional>や<algorithm>などを試してみたくないからです。ちょっと考えてみてください。
セバスチャンマッハ

3
「名前のない名前空間で必要な定型コードは必要ないからです」?「ボイラープレートコード」とは何ですか?「namespace {」と「}」を超えた何か?
towi 2014

1
@ErikAronesty同じ名前の別のファイルに「ローカルクラス」がある場合、ODR違反を犯します。
LF

32

古い質問ですが、あまり重要ではないように見え(それ自体はそれほど重要はありません)、すでにかなり良い回答をいただいていますが、私はあなたの質問に答えようとします。私が答えたい理由は、言語が既存の言語に基づいている場合、標準の進化と言語設計の基本的な問題に関連しているためです。言語機能を非推奨、削除、または互換性のない方法で変更する必要があるのはいつですか。

C ++では、変換ユニット内でstaticキーワードを使用して、シンボル(変数または関数宣言)の可視性に影響を与えることができます。

実際のリンケージ。

n3092では、これは非推奨になりました。

非推奨は次のことを示します。

  • 意思将来的には、いくつかの機能を削除します。これは、非推奨の機能が次の標準リビジョンで削除されること、または「すぐに」削除する必要があること、あるいはまったく削除する必要があることを意味するものではありません。また、非推奨ではない機能は、次の標準リビジョンで削除される可能性があります。
  • その使用思いとどまらせる正式な試み。

後者の点が重要です。あなたのプログラムが次の基準によって、時には黙って破られないという正式な約束は決してありませんが、委員会は「合理的な」コードを破らないように努めるべきです。非推奨は、プログラマーに、いくつかの機能に依存することは不合理であることを伝える必要があります

ただし、Cとの互換性(およびCプログラムをC ++としてコンパイルする機能)のために、非推奨は煩わしいことを強調しています。ただし、CプログラムをC ++として直接コンパイルすることは、すでに苛立たしい経験になる可能性があるため、検討する必要があるかどうかはわかりません。

特にヘッダーファイルの場合、C / C ++共通サブセットを保持することが非常に重要です。もちろん、staticグローバル宣言は内部リンケージを持つシンボルの宣言であり、これはヘッダーファイルではあまり役に立ちません。

しかし、問題はCとの互換性だけではなく、既存のC ++との互換性ですstatic。グローバル宣言を使用する既存の有効なC ++プログラムがたくさんあります。このコードは、正式に合法であるだけでなく、意図された方法で明確に定義された言語機能を使用しているため、健全です。

何かをするための「より良い方法」(ある人によると)があるからといって、プログラムが古い方法で書かれたものを「悪い」または「不合理」にするわけではありません。staticグローバルスコープでのオブジェクトと関数の宣言でキーワードを使用する機能は、CコミュニティとC ++コミュニティの両方でよく理解されており、ほとんどの場合正しく使用されます。

同様の静脈では、私はCスタイルのキャストには変更するつもりはないdoublestatic_cast<double>理由だけで、「Cスタイルのキャストが悪い」としてstatic_cast<double>、ゼロ情報とゼロの安全性を追加します。

何かをするための新しい方法が発明されるときはいつでも、すべてのプログラマーが既存の明確に定義された作業コードを書き直そうと急ぐという考えはただクレイジーです。継承されたCの醜さと問題をすべて削除したい場合は、C ++を変更せずに、新しいプログラミング言語を発明します。1回の使用を半分削除してもstatic、C ++の醜さが少なくなることはほとんどありません。

コードの変更には正当化が必要であり、「古いものは悪い」がコードの変更を正当化することは決してありません。

言語の変更を破るには、非常に強力な正当化が必要です。言語をごくわずかに単純化することは、重大な変更を正当化することにはなりません。

なぜstatic悪いのかという理由は非常に弱く、オブジェクトと関数の宣言の両方が一緒に非推奨にならない理由は明らかではありません-それらに異なる処理を与えると、C ++が単純になったり直交したりすることはほとんどありません。

だから、本当に、それは悲しい話です。それが持っていた実際的な結果のためではありません:それはまったく実際的な結果を持っていませんでした。しかし、それはISO委員会からの常識の明らかな欠如を示しているからです。


5
あなた自身が指摘しているように、それを非推奨にすることのポイントは、それの使用を思いとどまらせることです。しかし、あなたはその使用を思いとどまらせることが間違っているという議論をしません。匿名の名前空間に対して名前空間スコープの静的宣言を使用するように人々に勧めている人がいないことを私は確かに望んでいます。彼らは、特にクロスコンパイルC.する必要はありませない限り
ニコルボーラ

2
私は、グローバルスコープstaticや匿名の名前空間を使用している人々についてはあまり気にしません。私も奨励も落胆もしていません。私のポイントは、匿名の名前空間を使用することを本当に思いとどまらせたいのであれば、彼らに良い議論をしなければならないということです。実際には、ほとんどの実装では、名前のない名前空間で宣言されたエンティティはランダムな名前でエクスポートされたシンボルであるため、エクスポートテーブルが大きくなると思います。staticOTOHとして宣言されたエンティティは、いかなる方法でもエクスポートされません。したがって、多くの人々は、その観察に基づいて、を使用することを選択しますstatic
curiousguy 2011

2
あなた自身が指摘しているように、それを非推奨にすることのポイントは、それの使用を思いとどまらせることです。」その使用を思いとどまらせることのポイントは、それがいつか消えるかもしれないということです。私のポイントは、名前空間スコープstaticが消えることはないので、非推奨にするのは間違っているということです。「それでも、その使用を思いとどまらせることが間違っているという議論はありません。」名前空間スコープの使用staticが「間違っている」ことを示す説得力のある議論は見たことがありません。使用を思いとどまらせるためだけに非推奨にするのは間違っています。なぜなら、実際にはそれが消えるとは誰も信じていないからです。また、使用が「間違っている」と人々に納得させないからです。
curiousguy 2011

5
ホールランゲージは「いつか消える」でしょう。C ++を廃止しましょう。
軌道上でのライトネスレース2013年

2
「同様に、static_cast <double>は情報と安全性をゼロにするため、「Cスタイルのキャストが悪い」という理由だけで、Cスタイルのキャストをdoubleからstatic_cast <double>に変更するつもりはありません。」あるプリミティブから別のプリミティブへのCスタイルのキャストの自由な使用について不平を言い続ける多くのソフトウェアエンジニアとの私の永遠の戦い。
マコガン

14

非推奨かどうかにかかわらず、この言語機能を削除すると、既存のコードが破損し、人々を困らせることになります。

静的な非推奨の全体は、「匿名の名前空間は静的よりも優れている」および「参照はより優れたポインターである」という希望的観測でした。笑。


1
「参照はより良いポインタです」?いいえ、スマートポインタはよりスマートなポインタです。ヒープ、エラー、フリーストアから割り当てられたメモリの参照を使用することはできません。
ダンブレスラウ

3
すみません、皮肉なスマイリーで終わらせるのを忘れました。
Maxim Egorushkin 2011年

2
@ダン:それはまさにこの答えが言っていることです:同様の誤った考え方に沿った「希望的観測」。名前のない名前空間は、global-scope-staticと同じように重要な機能ですが、理由は少し異なりますが、適用性に多少の重複があります。
Fred Nurk 2011年

@ Fred、@ Maxim:誤解した場合、または記憶に欠陥がある場合は申し訳ありません。しかし、希望的観測の場合として、「参照はより良いポインタである」を「匿名の名前空間は静的よりも優れている」と同等であるとは分類しません。私は後者をスティックにしようとする試みをよく知っていますが、ポインターを参照に置き換えることを真剣に提案した人は誰も覚えていません。繰り返しますが、おそらくそれは私自身の意識に欠けています。
ダンブレスラウ

1
@DanBreslau:char* foo = new char; char& ref = *foo;ポインタが与えられたからといって、最初は参照を使用する能力について何も言いません。
軌道上でのライトネスレース2012年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.