web-dev-qa-db-ja.com

CとC ++のconstの正確さ

私はconstの正確さの意味を理解しています。私の質問はconstの正確さについてではありません。そのため、説明やC++-FAQリンクは期待していません。

私の質問は:

  • CのconstとC++のconstの意味上の違いは何ですか?および
  • 違いの理由は何ですか?

相違点を明確にするそれぞれの標準からの引用はあるといいでしょう。

私はCとC++を定期的に切り替えていますが、その際に留意すべき重要な点を知りたいのです。

私はこれらの理由を覚えていないようです(推論を提供できる場合は特に感謝します)が、私の頭の中から覚えています。

  • c ++のconst変数にはデフォルトで内部リンケージがありますが、Cではデフォルトで外部リンケージがあります。
  • constオブジェクトは、C++ではコンパイル時の値として使用できますが、Cではコンパイル時の値として使用できません。
  • 文字列リテラルへのポインターは、C++ではchar const*でなければなりませんが、Cではchar*にすることができます。

何が欠けていますか?

61
Alok Save

あなたが引用する違い、およびスティーブ・ジェソップが言及するライブラリの違いに加えて、

char* p1;
char const* const* p2 = &p1;

c ++では合法ですが、Cでは合法ではありません。歴史的に、これはCが最初に許可したためです。

char* p1;
char const** p2 = &p1;

標準が採用される少し前に、これがconstの安全性に穴を開けたことに気づきました(*p2char const*を割り当てることができるため、p1char const*が割り当てられるため)。問題を詳細に分析するリアルタイムがないため、C委員会はトップレベルのconst以外の追加のconstを禁止しました。 (つまり、&p1char **またはchar **constに割り当てることはできますが、char const**char const* const*に割り当てることはできません。)C++委員会はさらに分析を行い、constレベルの後にのみ問題が存在することを認識しましたconstレベルではなく、必要な表現を理解しました。 (標準の§4.4/ 4を参照してください。)

24
James Kanze

Cでは、const宣言は定数式を生成しません。つまり、Cでは、ケースラベルでconst intオブジェクトをビットフィールド幅または非VLAの配列サイズとして使用できません。配列宣言(これはすべてC++で可能です)。また、constオブジェクトには、Cのデフォルトで外部リンケージがあります(C++の内部リンケージ)。 C++言語のconst-correctnessルールは、次の標準変換をサポートしています

int **pp = 0;
const int *const *cpp = pp; // OK in C++

int ***ppp = 0;
int *const *const *cppp = ppp; // OK in C++

これらはcでは機能しません。

10

これらの違いのいくつかの理由は、Bjarneの初期の設計目標の1つであったプリプロセッサマクロを削除できるようにするためです。

Cでは

 #define MAX_FOOS 10
 int foos[MAX_FOOS];

C++では、次のように記述できるようにします

 const int max_foos = 10;
 int foos[max_foos];

そのためには、max_foosが定数式で使用できる必要があります。また、内部リンケージが必要です。これにより、定義が複数の定義エラーを発生させることなくヘッダーに表示され、さらに重要なことに、コンパイラーがmax_foosにストレージを割り当てないようにすることが容易になります。

C委員会がC++からconstを採用したとき、彼らはマクロへの反感を採用しなかったので、これらのセマンティクスを必要としませんでした。

5
Alan Stokes