サイズとして変数が与えられた文字配列を持つこのコードがコンパイルされるのはなぜですか?

ユーザー10482

テンプレートをいじってみると、C ++では許可されていないと思っていた、配列とそのサイズの定義に関する興味深い現象に遭遇しました。

main()内の配列のサイズを定義するためにグローバル変数を使用しましたが、何らかの理由で機能しました(以下のコードを参照)

1)なぜこれがコンパイルされるのですか?配列サイズにはconstexprのみを使用できると思いました

2)上記が有効であるとすると、文字列のサイズよりも明らかに小さいsz = 8の場合でも、なぜ機能するのかは説明されていません。

3)なぜ私たちはその奇妙な「@」と「?」を取得しているのですか?文字列のさまざまな組み合わせを試しました。たとえば、数字のみ( "123456789")でしたが、表示されませんでした。

助けに感謝します。ありがとう。

これが私のコードです

#include <iostream>
#include <cstring>


using namespace std;


int sz = 8;

int main()
{
    const char temp[sz] = "123456abc"; //9 characters + 1 null?

    cout << temp << endl;

    return 0;
}

出力:

123456ab @

user4581301

1)なぜこれがコンパイルされるのですか?配列サイズにはconstexprのみを使用できると思いました

質問者は、可変長配列(VLA)が標準C ++ではないということは正しいです。g ++コンパイラには、拡張機能によるVLAのサポートが含まれています。どうすればいいの?コンパイラ開発者は、標準で要求される動作が満たされている限り、必要なものをほとんど追加できます。動作を文書化するのは開発者次第です。

2)上記が有効であるとすると、文字列のサイズよりも明らかに小さいsz = 8の場合でも、なぜ機能するのかは説明されていません。

通常、配列が配列のサイズを超える値で初期化されると、g ++はエラーを発行します。この場合、C ++標準でエラーが必要かどうかを確認するには、ドキュメントで確認する必要があります。エラーが発生するのは良い場所のようですが、エラーが必要かどうかは思い出せません。

この場合、VLA拡張機能には、g ++が配列を過剰に埋めようとして通常吐き出すエラーを排除する副作用があるようです。コンパイラは、一般的な場合、コンパイル時に配列のサイズを認識せず、テストを実行できないため、これは非常に理にかなっています。テストもエラーもありません。

VLAはサポートされていないため、これはC ++標準ではカバーされていません。

VLAを許可するC標準をざっと見ても、この場合のガイダンスは見つかりませんでした。CVLAを初期化するためのルールは非常に単純です。できません。コンパイラは、コンパイル時に配列の大きさがわからないため、初期化できません。文字列リテラルには例外があるかもしれませんが、私はそれを見つけていません。

また、GCCドキュメントで動作の適切な説明を見つけられませんでした。

clangは、C標準の読み取りに基づいて予想されるエラーを生成しますエラー:可変サイズのオブジェクトが初期化されていない可能性があります

補遺:おそらく最初にStack Overflowをチェックして、多くの時間を節約する必要がありました:可変長配列を初期化しています

3)なぜ私たちはその奇妙な「@」と「?」を取得しているのですか?文字列のさまざまな組み合わせを試しました。たとえば、数字のみ( "123456789")でしたが、表示されませんでした。

起こっているように見えますが、これは標準ではないので、バックアップする引用符はありません。文字列リテラルがVLAのサイズまでVLAにコピーされます。VLAの終わりを過ぎたリテラルの部分は、黙って破棄されます。これにはヌルターミネータが含まれ、終了していないchar配列を出力するときの動作は定義されていません

解決:

可能な場合は、標準化された動作に固執します。主要なコンパイラには、非標準コードについて警告するオプションがあります。-pedanticgccオプションを使用するコンパイラーおよび/permissive-最近のバージョンのVisualStudioで使用します標準の外に出ることを余儀なくされた場合、スティッキーまたは文書化されていないビットについては、コンパイラのドキュメントまたは実装者自身に相談してください。

良い答えが得られない場合は、別の方法を探してみてください。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

コンパイル時に定義された配列のサイズを超える数の要素を配列に含めることは可能ですか?

分類Dev

このテンプレート化された関数が配列のコンパイルをゼロ初期化しないのはなぜですか?

分類Dev

Java配列で最大のものを見つけるこの汎用メソッドがコンパイルされないのはなぜですか?

分類Dev

継承を使用して、C ++でコンパイルされたコードのサイズを減らすことはできますか?

分類Dev

Javaコンパイラがこの変数が常に初期化されていることを理解しないのはなぜですか?

分類Dev

Javaでコマンドライン引数が文字列配列として渡されるのはなぜですか?

分類Dev

このコードがコンパイルされているのはなぜですか?

分類Dev

関数のパラメーターとして渡されるときに配列のサイズが異なるのはなぜですか

分類Dev

STLがこれをコンパイルするために一時的なイテレータ変数を必要とするのはなぜですか?

分類Dev

配列のサイズについて言及していなくても、コンパイルして実行するとコードが正常に機能するのはなぜですか?

分類Dev

if-casesで定義された変数がリークしますか?(別名、なぜこれがコンパイルされるのですか?)

分類Dev

「+ +」を含むこのJavaコードがコンパイルされるのはなぜですか?

分類Dev

このコマンドが、要素が入力された配列ではなく、予想されるサイズの空の配列を出力するのはなぜですか?

分類Dev

このコードがMSVC ++ではなくg ++でコンパイルされるのはなぜですか?

分類Dev

このランダムコードを維持して同じオッズを維持しながら、100アイテムから125アイテムに変更するにはどうすればよいですか?それでも100と同じパーセンテージである必要があります

分類Dev

非最終変数の参照:なぜこのコードはコンパイルされるのですか?

分類Dev

コードをコンパイルするためにこれらの正確なライフタイムが必要なのはなぜですか?

分類Dev

文字列が母音で始まるかどうかをチェックするコードがコンパイルされないのはなぜですか?

分類Dev

関数が他の場所で宣言された文字列配列のスライスのサイズを変更することは可能ですか?golang

分類Dev

パッケージの合計インストールサイズが、ダウンロードされたバイナリの複数のサイズになることが多いのはなぜですか?

分類Dev

コンテナが与えられたサイズを尊重しないのはなぜですか?

分類Dev

コントロールがC#Winformsで親にドッキングされているときに、デザイナーがコントロールの「サイズ」プロパティを設定するのはなぜですか?

分類Dev

Bash-ループ内のこれら2つのコマンドが並列ではなく連続して実行されるのはなぜですか?

分類Dev

構造体がメンバーとして「それ自体の型へのポインタ」を持つことが許可されているのに、「構造体型(の配列)」自体は許可されていないのはなぜですか?

分類Dev

Powershellから呼び出されたときにこのFFMPEGコマンドがホワイトノイズを生成するのはなぜですか?

分類Dev

ローカライズされた変数が数値として表示されるのはなぜですか?

分類Dev

コンパイラが関数のオーバーロードされたバージョンを見つけられないのはなぜですか?

分類Dev

変数の後に文字列リテラルがある場合、Javaコンパイラーはなぜそれを連結しないのですか?

分類Dev

パンダを使用してWebサイトからテーブルをスクレイプすると、中央の列がスキップされ、最初の2つと最後の2つだけが印刷されるのはなぜですか。

Related 関連記事

  1. 1

    コンパイル時に定義された配列のサイズを超える数の要素を配列に含めることは可能ですか?

  2. 2

    このテンプレート化された関数が配列のコンパイルをゼロ初期化しないのはなぜですか?

  3. 3

    Java配列で最大のものを見つけるこの汎用メソッドがコンパイルされないのはなぜですか?

  4. 4

    継承を使用して、C ++でコンパイルされたコードのサイズを減らすことはできますか?

  5. 5

    Javaコンパイラがこの変数が常に初期化されていることを理解しないのはなぜですか?

  6. 6

    Javaでコマンドライン引数が文字列配列として渡されるのはなぜですか?

  7. 7

    このコードがコンパイルされているのはなぜですか?

  8. 8

    関数のパラメーターとして渡されるときに配列のサイズが異なるのはなぜですか

  9. 9

    STLがこれをコンパイルするために一時的なイテレータ変数を必要とするのはなぜですか?

  10. 10

    配列のサイズについて言及していなくても、コンパイルして実行するとコードが正常に機能するのはなぜですか?

  11. 11

    if-casesで定義された変数がリークしますか?(別名、なぜこれがコンパイルされるのですか?)

  12. 12

    「+ +」を含むこのJavaコードがコンパイルされるのはなぜですか?

  13. 13

    このコマンドが、要素が入力された配列ではなく、予想されるサイズの空の配列を出力するのはなぜですか?

  14. 14

    このコードがMSVC ++ではなくg ++でコンパイルされるのはなぜですか?

  15. 15

    このランダムコードを維持して同じオッズを維持しながら、100アイテムから125アイテムに変更するにはどうすればよいですか?それでも100と同じパーセンテージである必要があります

  16. 16

    非最終変数の参照:なぜこのコードはコンパイルされるのですか?

  17. 17

    コードをコンパイルするためにこれらの正確なライフタイムが必要なのはなぜですか?

  18. 18

    文字列が母音で始まるかどうかをチェックするコードがコンパイルされないのはなぜですか?

  19. 19

    関数が他の場所で宣言された文字列配列のスライスのサイズを変更することは可能ですか?golang

  20. 20

    パッケージの合計インストールサイズが、ダウンロードされたバイナリの複数のサイズになることが多いのはなぜですか?

  21. 21

    コンテナが与えられたサイズを尊重しないのはなぜですか?

  22. 22

    コントロールがC#Winformsで親にドッキングされているときに、デザイナーがコントロールの「サイズ」プロパティを設定するのはなぜですか?

  23. 23

    Bash-ループ内のこれら2つのコマンドが並列ではなく連続して実行されるのはなぜですか?

  24. 24

    構造体がメンバーとして「それ自体の型へのポインタ」を持つことが許可されているのに、「構造体型(の配列)」自体は許可されていないのはなぜですか?

  25. 25

    Powershellから呼び出されたときにこのFFMPEGコマンドがホワイトノイズを生成するのはなぜですか?

  26. 26

    ローカライズされた変数が数値として表示されるのはなぜですか?

  27. 27

    コンパイラが関数のオーバーロードされたバージョンを見つけられないのはなぜですか?

  28. 28

    変数の後に文字列リテラルがある場合、Javaコンパイラーはなぜそれを連結しないのですか?

  29. 29

    パンダを使用してWebサイトからテーブルをスクレイプすると、中央の列がスキップされ、最初の2つと最後の2つだけが印刷されるのはなぜですか。

ホットタグ

アーカイブ