C autoキーワードはどこで使用されていますか?


104

大学時代にautoキーワードについて読んだのですが、実際にそれを忘れていました。次のように定義されます。

ローカル変数をローカル有効期間を持つものとして定義します

どこで使用されているかはわかりませんが、実際に使用されていますか。使用されている場合、どこで使用されていますか。

回答:


90

autoのような修飾子ですstatic。変数のストレージクラスを定義します。ただし、ローカル変数のデフォルトはであるため、auto通常は手動で指定する必要はありません。

このページには、Cのさまざまなストレージクラスがリストされています。


13
誰かが私の回答に賛成票を投じた後、これをもう一度見ていました。「通常は手動で指定する必要はありません」と言います。私はただ尋ねる必要があります:実際に指定auto できるがデフォルトでは発生しない状況はありますか?
Jerry Coffin 2013年

2
@JerryCoffin Cにはありません。C++ 11では再利用され、ローカル変数の型推論を効果的に取得するために使用できます。
Mehrdad Afshari 2013

2
可能な用途の1つは、GNU Cでの入れ子関数の前方宣言です。これは、の元の定義のハイジャックですautotigcc.ticalc.org/doc/keywords.html#auto
josiah

2
リンクされているページは古くなっています。C11以降、_Thread_local詳細もあります:en.cppreference.com/w/c/language/storage_durationおよびstackoverflow.com/a/14289720/6557621
MCCCS

132

IAQ(低頻度の質問)リストを読むと、autoが主に車両を定義または宣言するのに役立つことがわかります。

auto my_car;

常に屋外に駐車されている車両:

extern auto my_car;

ユーモアのセンスに欠けていて、「事実だけ奥様」を欲しがっている人たちのために:短い答えは、使用する理由がまったくないということautoです。使用autoが許可されるのは、autoストレージクラスが既にある変数を使用するときだけなので、とにかく起こることを指定するだけです。ストレージクラスをまだauto持たない変数で使用しようとするautoと、コンパイラがコードを拒否します。技術的になりたいのであれば、実装はコンパイラである必要はありませんが(実際はそうです)、診断を発行した後も理論的にはコードをコンパイルし続けることができます(ただし、そうではありません)。

kazによる小さな補遺:

もあります:

static auto my_car;

これは、ISO Cに基づく診断が必要です。これは、自動車が故障していることを宣言しているため、正しいです。診断は無料ですが、ダッシュボードのライトをオフにすると80ドルかかります。(eBayからオンボード診断用に独自のUSBドングルを購入した場合は20以下)。

前述の場合extern auto my_carも診断が必要です。そのため、駐車場の執行を担当する市職員以外は、コンパイラーを介して実行されることはありません。

extern static auto ...コードベースに多くが表示されている場合は、悪い地域にいます。場所全体が錆に変わる前に、すぐにもっと良い仕事を探してください。


@self .: ISOが「ISO 2011」を認識していないようです。それが標準化するかもしれないと何を信じますか
Jerry Coffin 2014年

6
口の中にコーヒー、コーラ、スタウト、またはその他の暗い色の液体が入っていなかったのは良いことです。その場合は、@ JerryCoffinというコンピューター画面が必要です。最高の答え!
David Hammen 2016年

2
@Dan:正直に言って、5行のテキストを読むのに「しばらく」かかり、「短い答えは、autoを使用する理由がまったくない」という部分にたどり着きましたか?マジ?あなたのコメントの直前のコメントを考えると、少なくとも数人の人がそれが前向きな貢献だと思っているようです。
ジェリーコフィン

@JerryCoffin私はすでにそれを説明しました、私のコメントをもう一度読んでください。Hindsightは20/20です。
Dan Bechard、2017年

2
私は最近の必要性を示唆している深刻な大火(2つのレーンを閉じて)合格char auto my_car;
スターク

46

autoキーワードは、C言語では無駄です。これは、C言語の前に、ローカル変数を宣言するためにそのキーワードが必要なB言語が存在していたためです。(BはNBに開発され、Cになりました)。

Bリファレンスマニュアルです

あなたが見ることができるように、マニュアルautoは使用される例でいっぱいです。これはintキーワードがないためです。「これは変数の宣言です」と言うためにある種のキーワードが必要であり、そのキーワードはそれがローカルであるか外部であるか(autoextrn)であることも示します。どちらかを使用しないと、構文エラーになります。つまりx, y;、それ自体は宣言ではなく、そうauto x, y;です。

Bで記述されたコードベースは、言語の開発に応じてNBとCに移植する必要があったため、新しいバージョンの言語では、下位互換性を向上させるために手間がかかり、作業が少なくなりました。の場合auto、プログラマーは出現するすべてのものを探し出してauto削除する必要はありませんでした。

マニュアルから明らかなように、陳腐化した「暗黙のint」Cの残骸(前にmain() { ... }何もない状態intで書き込むことができる)もBから来ています。これは、Bコードをサポートするもう1つの下位互換性機能です。型がないため、関数にはBで指定された戻り型はありません。多くのアセンブリ言語のように、すべてが単語です。

関数がどのように宣言されるか、extrn putcharそしてそれを識別子が使用する関数にする唯一の方法に注意してください。それはのような関数呼び出し式で使用され、それがputchar(x)コンパイラーにその型のない単語を関数ポインターとして扱うように指示します。


24

Cではauto、変数がブロックに対してローカルであることを示すキーワードです。これはブロックスコープ変数のデフォルトであるため、不要であり、使用されることはほとんどありません(キーワードについて説明しているテキストの例の外で使用されたことはないと思います)。auto正しい構文解析または動作を得るためにの使用が必要だったケースを誰かが指摘できるかどうか、興味があります。

ただし、C ++ 11標準では、auto型推論をサポートするためにキーワードが「ハイジャック」されています。変数の型は、初期化子の型から取得できます。

auto someVariable = 1.5;   // someVariable will have type double

型推論は、主にテンプレート内の変数の宣言をサポートするために追加されているか、テンプレート関数に基づいて返される(または、テンプレートがインスタンス化されるときにコンパイラーによって推定される)手動で宣言するのが非常に面倒な場合があります。


1
「変数はブロックに対してローカルです」—それはまったく真実ではありません。ブロックで宣言されたすべての変数は、そのスコープに対して(スコープに関して)ローカルです。それらはプログラム内の他の変数にリンクされている可能性がありますが、宣言はそのブロックでのみ表示されます。 auto可視性とは何の関係もないストレージクラスについてです。
fuz

12

古いAztec Cコンパイラでは、コマンドラインスイッチを使用して、すべての自動変数を静的変数に変換することができました(アドレス指定の速度を向上させるため)。

ただし、明示的に宣言された変数autoはそのまま残されていました。(他の方法では適切に機能しない再帰関数には必須です!)


7

このautoキーワードは、Pythonにセミコロンを含めるのと似ていますが、以前の言語(B)で必要でしたが、開発者は、ほとんどのものがだったので冗長であることに気付きましたauto

BからCへの移行を支援するために残されたと思います。要するに、1つの用途はB言語の互換性のためです。

たとえば、Bと80年代のCの場合:

/* The following function will print a non-negative number, n, to
   the base b, where 2<=b<=10.  This routine uses the fact that
   in the ASCII character set, the digits 0 to 9 have sequential
   code values.  */

printn(n, b) {
        extrn putchar;
        auto a;

        if (a = n / b)        /* assignment, not test for equality */
                printn(a, b); /* recursive */
        putchar(n % b + '0');
}

1

Autoキーワードは、ストレージクラス(変数の寿命とストレージ場所を決定するある種の手法)の例です。それは、そのキーワードのヘルプによって作成された変数が中括弧内にのみ存続する寿命(lifetime)を持つ動作を持っています

{
    auto int x=8;        
    printf("%d",x);  // here x is 8

    { 
        auto int x=3;
        printf("%d",x);  // here x is 3
    }              

    printf("%d",x);  // here x is 8
}          

0

autoブロックスコープの変数にのみ使用できます。extern auto intコンパイラーは外部定義を使用するかどうか、またはexternをauto定義でオーバーライドするかどうかを判別できないため、これはゴミです(autoとextern static auto intも、明らかにゴミのように、まったく異なるストレージ期間です)。常に1つの方法で解釈することを選択できますが、代わりにエラーとして処理することを選択します。

auto提供し、関数内の「すべてがint」ルールを有効にする機能が1つあります。関数の外部とは異なり、ファイルスコープに割り当てが存在しないためにa=3が定義として解釈されるint a =3場合a=3、コンパイラは常にそれを定義ではなく外部変数への割り当てとして解釈するため(明らかに何もしないextern int a機能やファイルスコープでの前方宣言が)、しかし、のような指定staticconstvolatileまたはautoそれが定義され、コンパイラは除き、定義としてそれを取ることを暗示するauto他の指定子の副作用はありません。auto a=3したがって、暗黙的auto int a = 3です。確かに、signed a = 3同じ効果があり、unsigned a = 3常にunsigned intです。

また、「autoオブジェクトがレジスターに割り当てられるかどうかには影響しません(特定のコンパイラーがオブジェクトに注意を払わない限り、そうではないようです)。」


-1

「extern」、「static」、「register」、および「auto」であるCのストレージクラス指定子に精通していると思います。"auto"の定義は他の回答でほとんど与えられていますが、ここでは "auto"キーワードの可能な使用法がわかりませんが、コンパイラーに依存していると思います。ご覧のとおり、ストレージクラス指定子に関してはルールがあります。変数に複数のストレージクラス指定子を使用することはできません。これが、静的グローバル変数を排除できない理由です。したがって、彼らは自分のファイルだけに知られています。コンパイラ設定に移動すると、最適化フラグを有効にして速度を上げることができます。コンパイラーが最適化する方法の1つは、ストレージクラス指定子のない変数を探し、キャッシュメモリの可用性やその他の要因に基づいて評価を行い、レジスタ指定子を使用してその変数を処理する必要があるかどうかを確認します。ここで、プログラム内の特定の変数はそれほど重要ではなく、コンパイラーにそれをレジスターと見なさないようにしながら、コードを最適化して速度を上げたいとしたらどうでしょう。autoを指定すると、「register auto int a;」と入力してからコンパイラが変数にレジスタ指定子を追加できなくなります。または「auto register int a;」複数のストレージクラス指定子を使用するとエラーが発生します。まとめると、autoはコンパイラーが最適化を通じて変数をレジスターとして扱うことを禁止できると考えました。プログラム内の特定の変数はそれほど重要ではなく、コンパイラーにそれをレジスターと見なしてほしくないことを認識しながら、コードの速度を最適化したい場合はどうでしょうか。autoを指定すると、「register auto int a;」と入力してからコンパイラが変数にレジスタ指定子を追加できなくなります。または「auto register int a;」複数のストレージクラス指定子を使用するとエラーが発生します。まとめると、autoはコンパイラーが最適化を通じて変数をレジスターとして扱うことを禁止できると考えました。プログラム内の特定の変数はそれほど重要ではなく、コンパイラーにそれをレジスターと見なしたくない場合でも、コードの速度を最適化したい場合はどうでしょうか。autoを指定すると、「register auto int a;」と入力してからコンパイラが変数にレジスタ指定子を追加できなくなります。または「auto register int a;」複数のストレージクラス指定子を使用するとエラーが発生します。まとめると、autoはコンパイラーが最適化を通じて変数をレジスターとして扱うことを禁止できると考えました。複数のストレージクラス指定子を使用するとエラーが発生します。まとめると、autoはコンパイラーが最適化を通じて変数をレジスターとして扱うことを禁止できると考えました。複数のストレージクラス指定子を使用するとエラーが発生します。まとめると、autoはコンパイラーが最適化を通じて変数をレジスターとして扱うことを禁止できると考えました。

この理論はGCCコンパイラーでは機能しませんでしたが、他のコンパイラーは試していません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.