21

Linux カーネル ソースには、次のような多くの配列リテラルがあります。

enum {
  FOO,
  BAR
};

static const char* const names[] = {
  [FOO] = "foo", /* wtf is this? */
  [BAR] = "bar",
};

ここで、各行は、順序付けに依存するのではなく、指定された値の配列内のインデックスを明示的に示しています。

検索するフレーズがわかりません - これは何と呼ばれていますか? それを定義する基準は何ですか?(それとも GNU 拡張機能ですか?) C++ または単純な C でこれを行うことはできますか? を試してgccみると、上記の が見つかりましたtest.c

$ gcc --version
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE

これらのコマンドは成功を返します。

$ gcc -Wall -c test.c
$ gcc -Wall -c --std=c90 test.c
$ gcc -Wall -c --std=gnu90 test.c
$ gcc -Wall -c --std=iso9899:1990 test.c
$ gcc -Wall -c --std=c1x test.c

これらのコマンドは、ラムダと に関するさまざまな苦情で失敗しますoperator=

$ g++ -Wall -c test.c
$ g++ -Wall -c --std=c++98 test.c
$ g++ -Wall -c --std=gnu++98 test.c
$ g++ -Wall -c --std=c++0x test.c
$ g++ -Wall -c --std=gnu++0x test.c

これは、これが有効な C (ほぼすべての方言で) であることを示唆していますが、C++ ではありません。しかし、私は懐疑的です。これが Linux カーネル以外で使われているのを見た覚えがありません。また、たとえば、this list of constructs valid in C but not C++にも記載されていません。

4

2 に答える 2

13

これは、「指定された初期化」と呼ばれる標準 C (C99 以降) の一部です。

6.7.9 Initializationの段落 6から:

指定子がフォームを持っている場合

[ constant-expression ]

次に、現在のオブジェクト ... は配列型を持ち、式は整数定数式でなければなりません。配列のサイズが不明な場合、負でない値はすべて有効です。

そしてパラグラフ33:

例 9指定子を使用して、列挙型の要素に対応するように配列を初期化できます。

enum { member_one, member_two };
const char *nm[] = {
      [member_two] = "member two",
      [member_one] = "member one",
};

この質問 の回答によると、C++ は同じ動作をサポートしていません。コンパイラが拡張機能を提供している場合があります。

おそらくあなたにとってより役立つ(そしてあなたの質問への直接的な答え)は、GCCのドキュメントです。

ISO C99 では、適用する配列インデックスまたは構造フィールド名を指定して、要素を任意の順序で指定できます。GNU C では、C90 モードでも拡張としてこれを許可しています。この拡張機能は GNU C++ では実装されていません。

于 2013-07-10T21:21:01.710 に答える
12

c99指定のイニシャライザです。

指定初期化子を使用すると、配列または構造体を任意の順序で初期化できます。省略された要素は、静的オブジェクトであるかのように初期化されます。

int bla[16] = {[5] = 42, [9] = 42};

これにより、要素bla[5]bla[9]が初期化され42、残りのすべての要素が に初期化され0ます。指定は の間の整数定数式[]です。

enum {
  FOO,
  BAR
};

static const char* const names[] = {
  [FOO] = "foo", /* wtf is this? */
  [BAR] = "bar",
};

ここでの指定は列挙定数です。これは、C では列挙型定数が整数定数式と見なされるため、許可されています。

この機能は C の機能であり、C++ にはありません。

于 2013-07-10T21:21:29.533 に答える