3

struct netif *関数スコープ(コンパイルが文句を言わない)からグローバルスコープにaを宣言すると、gccで次のエラーが発生します。

src/main.c:114:3: warning: passing argument 1 of 'low_level_init' from incompatible pointer type [enabled by default]
src/main.c:62:13: note: expected 'struct netif *' but argument is of type 'struct netif *'

コンパイラが次の「無意味な」苦情を出すのはなぜですか?

expected 'stuct netif *' but argument is of type 'struct netif *'

4

4 に答える 4

4

この「フルプログラム」

void foonetif(struct netif *dst) {
  if (dst) return;
  return;
}

struct netif {
  double bar;
};

int main(void) {
  struct netif *netif = 0; /* NULL */
  foonetif(netif);
  return 0;
}

この出力はgcc 10398683.c(gccバージョン4.6.3)から生成されるため、すべてのデフォルトオプションを使用します

10398683.c:1:22:警告:'structnetif'がパラメータリスト内で宣言されました[デフォルトで有効]
10398683.c:1:22:警告:そのスコープはこの定義または宣言のみであり、おそらくあなたが望むものではありません[デフォルトで有効]
10398683.c:関数'main'内:
10398683.c:12:3:警告:互換性のないポインタ型から「newnetif」の引数1を渡します[デフォルトで有効]
10398683.c:1:6:注:「structnetif *」が必要ですが、引数のタイプは「structnetif*」です。

最後の警告に注意してください(本当にメモ):)

于 2012-05-01T14:08:30.983 に答える
2

問題はスコープです。1つ目struct netifは、関数の引数リストのスコープ内にあり、その関数が終了するとスコープ外になります。2つ目struct netifは、新しいスコープで定義されます。したがって、これらは、同じ名前を持つ異なるタグを持つ異なる構造タイプです。2つの異なる関数のようint i;int i;、同じ名前を持つ異なる変数があります。

于 2012-05-01T14:45:14.293 に答える
1

興味深い質問です。私自身、これに反則しました。主に、無実のメモリブロックへの疑わしい型キャストを含む恐ろしいハッキングが原因です。


この答えは、実際にはRの答えの当然の結果であり、問​​題をかなり釘付けにします(ただし、少しはよくわかりませんand goes out of scope after that function ends..) 。

私にとって、これの鍵は次のことを熟読することです:
(1)ISO C99 6.7.2

タイプが同じである場合、2つのタイプは互換性のあるタイプになります。2つの型が互換性があるかどうかを判断するための追加の規則は、型指定子については6.7.2、型修飾子については6.7.3、宣言子については6.7.5で説明されています46)。翻訳ユニットは、タグとメンバーが次の要件を満たしている場合に互換性があります。一方がタグで宣言されている場合、もう一方は同じタグで宣言されている必要があります。..。


(2)C名前空間


とにかく、ここにいくつかのコード(〜いくつかの翻訳ユニット)があります。これは、これまでこの問題にまだ遭遇していない人にとって、おそらく驚くべき動作を示すことを願っています。

blah.c:

#include <stdio.h>

struct bar  {int a; int b;} stbar; 
struct bar_ {int a; int d;} stbar_; 

void foo(struct bar* pst);
void foo_(struct bar st);


void callfoo() 
{ 
    /*no warnings; possibly surprising results ! */
    stbar.a=313;
    stbar.b=31313;
    foo(&stbar);
    printf("called foo() with stbar:  %d, %d\n", stbar.a, stbar.b);

    /*generates incompatible types warnings:
    blah.c:23:5: warning: passing argument 1 of ‘foo’ from incompatible pointer type [enabled by default]
    blah.c:6:6: note: expected ‘struct bar *’ but argument is of type ‘struct bar_ *’    */
    stbar_.a=313;
    stbar_.d=31313;
    foo(&stbar_);
    printf("called foo() with stbar_: %d, %d\n", stbar_.a, stbar_.d);


    /*generates incompatible types warnings:
    blah.c:31:5: warning: passing argument 1 of ‘foo’ from incompatible pointer type [enabled by default]
    blah.c:6:6: note: expected ‘struct bar *’ but argument is of type ‘struct bar *’      */
    struct bar  {float s; float t;} stbar; 
    foo(&stbar);
    printf("called foo() with locally defined stbar:  %f, %f\n", stbar.s, stbar.t);    
}


void callfoo_()
{
    stbar.a=313;
    stbar.b=31313;

    //passing in incompatible type by value ~ no warnings; possibly surprising results ! 
    foo_(stbar); 

    /*uncomenting next line generates compiler error: 
    blah.c:47:5: error: incompatible type for argument 1 of ‘foo_’
    blah.c:7:6: note: expected ‘struct bar’ but argument is of type ‘struct bar_’     */
    //foo_(stbar_); 
}


void main() 
{
    callfoo();
    callfoo_();
}

blah_.c:

#include <stdio.h>

struct bar {int x; float z;} stbar; 

void foo(struct bar* pst)
{
    printf("foo : %d, %f\n", pst->x, pst->z);
    pst->x=13;
    pst->z=13.13;
}

void foo_(struct bar st)
{
    printf("foo_ : %d, %f\n", st.x, st.z);
    st.x=13;
    st.z=13.13;
}

出力:

$ gcc  blah.c blah_.c
blah.c: In function ‘callfoo’:
blah.c:23:5: warning: passing argument 1 of ‘foo’ from incompatible pointer type [enabled by default]
blah.c:6:6: note: expected ‘struct bar *’ but argument is of type ‘struct bar_ *’
blah.c:31:5: warning: passing argument 1 of ‘foo’ from incompatible pointer type [enabled by default]
blah.c:6:6: note: expected ‘struct bar *’ but argument is of type ‘struct bar *’

$ ./a.out
foo : 313, 0.000000
called foo() with stbar:  13, 1095898235
foo : 313, 0.000000
called foo() with stbar_: 13, 1095898235
foo : 13274075, 0.000000
called foo() with locally defined stbar:  0.000000, 13.130000
foo_ : 313, 0.000000

$ gcc --version
gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1 ...


当然の結果:C++の神々を称賛しnamespaceます。

于 2012-05-01T19:14:06.847 に答える
0

あなたの「完全なプログラム」はコンパイルされません。

struct netifは、それを使用するfoonetifの前に宣言されていません。最初に使用する前に、構造体定義を移動してみてください。

于 2012-05-01T14:33:16.617 に答える