4

最近、MicrosoftのコンパイラからIntelC++コンパイラに移行した大規模なコードベースがあります。私たちのチームの目標は、メインラインで警告なしにコンパイルすることです。切り替え以来、警告167の1つのインスタンスが私を混乱させました。次のコードをコンパイルすると、次のようになります。

int foo(const int pp_stuff[2][2])
{
   return 0;
}

int foo2(const int pp_stuff[][2])
{
    return 0;
}


int main(void)
{
    int stuff[2][2] = {{1,2},{3,4}};

    foo(stuff);
    foo2(stuff);

    return 0;
}

ICCは私に警告を出します:

1>main.c(17): warning #167: argument of type "int (*)[2]" is incompatible with parameter of type "const int (*)[2]"
1>        foo(stuff);
1>            ^
1>  
1>main.c(18): warning #167: argument of type "int (*)[2]" is incompatible with parameter of type "const int (*)[2]"
1>        foo2(stuff);

なぜこれが警告である必要がありますか?非const変数をconstパラメーターとして渡すのが一般的な方法であり、タイプと次元は同じです。

これを重複した質問としてマークした人には、再考することをお勧めします。他の誰かがこの警告に遭遇した場合、Cの引数がプロトタイプ関数での割り当てによるかのように変換されることを知ってから、厳密に割り当てに関する質問を検索する必要があります。答えはC90/C99と同じ条項になりますが、質問はかなり異なると思います。

4

2 に答える 2

2

constを必要とする関数に変数を渡すときに、変数をconstとしてキャストします。

foo( (const int (*)[2]) stuff );

const char**を期待する関数にchar**を渡せないのはなぜですか?

同様の質問

于 2013-02-15T18:46:21.790 に答える
2

stuff配列の値はタイプint (*)[2]です。

int foo(const int pp_stuff[2][2])

と同等です

int foo(const int (*pp_stuff)[2])

関数呼び出しでは、型の値を型int (*)[2]の変数に割り当てているかのようになりますconst int (*)[2]

引数は、プロトタイプ関数での割り当てによるかのように変換されます。また、Cでは、次の場合に2つのポインタを割り当てることができます。

両方のオペランドは、互換性のある型の修飾バージョンまたは非修飾バージョンへのポインターであり、左側が指す型には、右側が指す型のすべての修飾子があります。

ここint (*)[2]const int (*)[2]は、同じタイプの修飾/非修飾バージョンではありません。修飾子はint、ポインターではなくに適用されます。

使用する:

int foo(int (* const pp_stuff)[2])

要素constではなくポインタを作成したい場合。int

于 2013-02-15T18:46:40.257 に答える