web-dev-qa-db-ja.com

GCC:配列型の要素型が不完全です

構造体を宣言し、それらの構造体の配列(およびdoubleのdouble配列、整数)を関数に渡そうとしています。コンパイルすると、gccから「配列型に不完全な要素型があります」というメッセージが表示されます。構造体を関数に渡す方法で何が間違っていますか?

typedef struct graph_node {
  int X;
  int Y;
  int active;
} g_node;

void print_graph(g_node graph_node[], double weight[][], int nodes);

私も試してみましたstruct g_node graph_node[]、しかし私は同じことを得る。

28
Joshua Soileau

問題を引き起こしているのは配列です:

_void print_graph(g_node graph_node[], double weight[][], int nodes);
_

2番目以降の次元を指定する必要があります。

_void print_graph(g_node graph_node[], double weight[][32], int nodes);
_

または、ポインタへのポインタを与えることができます:

_void print_graph(g_node graph_node[], double **weight, int nodes);
_

ただし、見た目は似ていますが、内部的には大きく異なります。

C99を使用している場合、可変修飾された配列を使用できます。 C99標準の例を引用(セクション6.7.5.2配列宣言子):

_void fvla(int m, int C[m][m]); // valid: VLA with prototype scope

void fvla(int m, int C[m][m])  // valid: adjusted to auto pointer to VLA
{
    typedef int VLA[m][m];     // valid: block scope typedef VLA
    struct tag {
        int (*y)[n];           // invalid: y not ordinary identifier
        int z[n];              // invalid: z not ordinary identifier
    };
    int D[m];                  // valid: auto VLA
    static int E[m];           // invalid: static block scope VLA
    extern int F[m];           // invalid: F has linkage and is VLA
    int (*s)[m];               // valid: auto pointer to VLA
    extern int (*r)[m];        // invalid: r has linkage and points to VLA
    static int (*q)[m] = &B;   // valid: q is a static block pointer to VLA
}
_

コメントの質問

[...] main()では、関数に渡そうとしている変数は_double array[][]_であるため、どのように関数に渡しますか? _array[0][0]_を渡すと、_&array_と_&array[0][0]_と同様に、互換性のない引数タイプが得られます。

main()では、変数は次のようになります。

_double array[10][20];
_

またはかすかに類似した何か;多分

_double array[][20] = { { 1.0, 0.0, ... }, ... };
_

次のようなコードでそれを渡すことができるはずです:

_typedef struct graph_node
{
    int X;
    int Y;
    int active;
} g_node;

void print_graph(g_node graph_node[], double weight[][20], int nodes);

int main(void)
{
    g_node g[10];
    double array[10][20];
    int n = 10;

    print_graph(g, array, n);
    return 0;
}
_

GCC 4.2(i686-Apple-darwin11-llvm-gcc-4.2(GCC)4.2.1(Apple Inc. build 5658に基づく))(LLVM build 2336.9.00))およびコマンドラインを使用したMac OS X 10.7.3上のGCC 4.7.0でも:

_/usr/bin/gcc -O3 -g -std=c99 -Wall -Wextra -c zzz.c
_
33

コンパイラは、2次元配列の2番目の次元のサイズを知る必要があります。例えば:

void print_graph(g_node graph_node[], double weight[][5], int nodes);
7
Ed S.