Cのconst修飾子とC ++のconst修飾子の違いは何ですか?


9

I'veが見つかりました。コメント、ユーザのRを...

CとC ++は同じ言語ではありません。特に、C constはC ++とは何の関係もありませんconst

constCのconst修飾子とC ++ の修飾子の違いの1つは、そのデフォルトのリンケージです。

constC ++では、修飾子を使用して名前空間スコープで宣言されたオブジェクトは内部リンケージを持ちますが、Cではconst、グローバルスコープで宣言された修飾子を持つオブジェクト(static前に修飾子を持たないconst)は外部リンケージを持ちます。

しかし、CとC ++の言語間で他にどのように異なるのですか?両方の言語で、どちらも同じ種類の概念と目的を持っていると思いました。

私の質問:

  • Cのconst修飾子とC ++のconst修飾子の違いは何ですか?

回答「ポーラ」はどのようにCとC ++で異なりますか?正確な差異指していないの文脈におけるCおよびC ++の言語const修飾子を。特定の言語で実行できない、または実行できることのみ。


非常に多くの答えがグーグル検索ですぐに見つかります。そのうちの一つ:stackoverflow.com/questions/4486442/...
schaiba

1
Cでは、constリンケージとは何の関係もありません。あなたはstatic constファイルスコープを持つことができ、それは内部リンケージを持っています
Lundin

3
その質問に対する現在の回答に不満がある場合(これはあなたと同じです)、賞金を投稿することを検討してください。
Sneftel

3
リンクされた複製が悪いことに同意します。良い答えは、すべての違いをリストすることでconstあり、両方の言語で同じことが何であるかをあまり説明しないでしょう。
ランディン

1
私はそのような答えを書くことを試みることができますが、すべての違いをカバーしていることを確認するのに十分なC ++の達人ではありません。C ++のconst変数は、Cとは異なり、定数式です。C++はメンバー関数を修飾することができます。上記のリンケージ。他に何か?
ランディン

回答:


11
  • 最も重要な違いは、C ++ではconst変数は定数式ですが(C ++ 11が導入される前でもconstexpr)、constCの変数はそうではありません。

    C ++では次のようなことを実行できますconst size_t n = 1; static int array[n];が、Cではそれを許可していません。これはおそらく歴史的な理由によるものです。

  • C ++では、constリンケージの決定に関与します。これはC ++バージョン間で異なります。cppreference.com(強調鉱山)によると:

    名前空間スコープで宣言された次の名前のいずれにも内部リンケージがあります。


    • 非揮発性非テンプレート(C ++ 14以降)非インライン(C ++ 17以降)非エクスポート(C ++ 20以降)constで修飾された変数(constexprを含む)は、externと宣言されておらず、以前に外部リンケージがあると宣言されている。

    Cではconstリンケージの決定にまったく関与しませんが、宣言スコープとストレージクラス指定子のみが重要です。

  • C ++では、constメンバー関数を修飾できます。Cではメンバー関数の構文サポートがないため、これは不可能です。

  • Cではconst、初期化子なしで-qualified変数を宣言できます。Cでは、const int x;初期化子なしで書くことができますが、C ++ではそれを許可していません。一見すると、これはCの意味のない言語バグのように思えるかもしれませんが、理論上、コンピューターには読み取り専用のハードウェアレジスタがあり、ソフトウェアではなくハードウェアによって値が設定されています。Cがハードウェア関連のプログラミングに適していることを意味します。


Cでメンバー関数を使用できますか?
Maxim Egorushkin

1
const size_t n = 1; static int array[n];コンパイラーがn定数の伝播の定義を確認して実行できる場合にのみ機能することに注意してください。extern const size_t n; static int array[n];動作しません。
Maxim Egorushkin

ええと、そのようなハードウェアレジスタはuint32_t const* x = reinterpret_cast<uint32_t const*>(20102012);... などのポインタを介してアドレス指定されていると思います
アコンカグア

@Aconcaguaそのようなレジスタは、レジスタマップの他の部分と互換性がなくなります。そして、それによって、デバッガで実際のレジスタ値を表示できるようになりますか?たとえば、読み取り専用のシリコンマスクセットレジスタを表示して、最終的にどの部分に到達したかをすばやく確認したい場合などです。そして、明らかに、volatileポインタを修飾する必要もあります。
ランディン

@Lundin認めた、注意を払っていなかったvolatile...残りの状況による これらの場合に手で持っていたデバッガーも簡単に解決でき*xました。一方、レジスタがいくつかのメモリ領域にマップされており、コンパイラが特定のメモリ位置に変数を直接配置することをサポートしていない場合(両方を確認しました)、特定のメモリ位置に変数を取得すると、ときどき乱雑になることがあります(マップファイルでそれをカバーする必要があります...)。結局、割り当てられたタスクを実行できる限り、変数を正しい場所に配置したり、ポインターを配置したりすることはあまり気にしません;)
アコンカグア

0

cppreference.comから:

const非局所非揮発性非テンプレートの宣言に使用される修飾子を非インライン宣言されていない(C ++ 17以降)変数は、(C ++ 14以降)externを与える内部リンケージ。これは、constファイルスコープ変数に外部リンケージがあるCとは異なります。

それ以外constは、CおよびC ++で同じセマンティクスを持ち、constCヘッダーは条件付きでC ++ヘッダーとしてコンパイルされることがよくあります"extern C"


1
それは悪い引用であり、単純化しすぎです。static const x;Cのファイルスコープには内部リンケージがあります。C変数のリンクは、それが宣言されているスコープ、およびストレージクラス指定子の有無によって決まります。const他の型修飾子は、その一部をまったく果たしません。
ランディン

@Lundinそれは引用が言うこととどう違うのですか?
Maxim Egorushkin

1
私が挙げた例は、引用が間違っていることを証明しています。引用によると、static const x;Cのファイルスコープには外部リンクがあります。
ランディン

@Lundin引用によればint const x = 1、Cには外部リンケージがある。したがって、staticリンケージを内部に変更する必要があります。あなたのコメントとは異なり、引用は私にはかなり明確です。
Maxim Egorushkin

1
それは本当にそれを全く言っていません。見積もりを読みます。"... C constファイルのスコープ変数に外部リンケージがある"。
ランディン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.