2

ポインターの2つの配列を比較して、それらが同じであるかどうかを確認する関数を作成しようとしています。ポインターの任意の配列でこの関数を使用したいのですが、つまり、ポインターが何を指しているかに関係なく、ポインター自体の同等性に関心があります。

私はこれを書いた:

/**
 * Return true if arrays (of type ptr to ptr) are equal
 */
bool ptr_array_eq(const void **x, const void **y, size_t n)
{
    size_t i;
    for (i=0; i<n; i++) {
        if (x[i] != y[i]) {
            return false;
        }
    }
    return true;
}

私のユニットテストは次のようになります。

void testPTR_ARRAY_EQ(void)
{
    Mode *m1, *m2, *m3, *m4, *m5, *m6;

    Mode *a[] = {m1, m2, m3, m4, m5};
    Mode *b[] = {m1, m2, m3, m4, m5};
    Mode *c[] = {m2, m3, m4, m5, m6};
    Mode *d[] = {m1, m3, m4, m5, m6};

    CU_ASSERT(ptr_array_eq(a, a, 4));
    CU_ASSERT(ptr_array_eq(a, b, 4));
    CU_ASSERT(! ptr_array_eq(a, c, 4));
    CU_ASSERT(! ptr_array_eq(a, d, 4));
}

しかし、コンパイルすると、次の警告が表示されます(エラーではありません)。

test_utility.c: In function ‘testPTR_ARRAY_EQ’:
test_utility.c:648:5: warning: passing argument 1 of ‘ptr_array_eq’ from incompatible pointer type [enabled by default]
../src/glamdring2.h:327:6: note: expected ‘const void **’ but argument is of type ‘struct Mode **’

私のユニットテストで、使用している型が関数プロトタイプと一致しないとコンパイラが文句を言っています

しかし、私は基礎となる型にはあまり興味がなく、それへのポインタだけに興味があります。するべきか:

  • a)警告を無視する
  • b)コンパイラが警告を出さないように関数を書き直します
  • c)着信ポインタのキャストを実行します
  • d)Cが基になる型を知らないという考えを好まないことを受け入れ、遭遇する可能性のあるポインタの型ごとに関数を書き直します。
4

1 に答える 1

3

関数には、の配列(の最初の要素へのポインタ)が必要ですconst void*

の配列(の最初の要素へのポインタ)を渡そうとしていますMode*

これはCでは許可されていません。これは(他の理由の中でも)C標準によって同じサイズvoid*であることが保証されていないためです。Mode*したがって、この言語では、プログラムが誤って一方の配列を他方の配列であるかのように処理することはありません。

実装固有の詳細がわかりやすく、ほとんどすべての実装に含まれていることを条件としてmemcmp、配列を比較するために使用できます。

于 2012-07-10T08:32:46.923 に答える