【问题标题】:Compilation error about a union field in another union关于另一个联合中的联合字段的编译错误
【发布时间】:2014-03-07 02:00:19
【问题描述】:

考虑下面的代码,我已经写了:

#include <stdio.h>
#include <stdint.h>

union myAccess {
    uint16_t access16;
    struct {
        uint8_t lo;
        uint8_t hi;
        } access8;
    };

union myByte{
    uint8_t  BYTE;
    struct {
        unsigned BIT0:1;
        unsigned BIT1:1;
        unsigned BIT2:1;
        unsigned BIT3:1;
        unsigned BIT4:1;
        unsigned BIT5:1;
        unsigned BIT6:1;
        unsigned BIT7:1;
        }BIT;
    };

int main()
{

   union myAccess U;
   U.access8.lo=0xF1;
   U.access8.hi=0x55;
   printf("%x\n",U);


   union myByte B;
   B.BYTE=0;
   B.BIT.BIT4=1;
   printf("%x\n",B);

    return 0;
}

输出是:

Gaurav@Gaurav-PC /cygdrive/d
$ ./LSI
2255f1
61279210

现在当我修改我的代码如下:

#include <stdio.h>
#include <stdint.h>

union myAccess {
    uint16_t access16;
    struct {
        uint8_t lo;
        union myByte hi;//here
        } access8;
    };

union myByte{
    uint8_t  BYTE;
    struct {
        unsigned BIT0:1;
        unsigned BIT1:1;
        unsigned BIT2:1;
        unsigned BIT3:1;
        unsigned BIT4:1;
        unsigned BIT5:1;
        unsigned BIT6:1;
        unsigned BIT7:1;
        }BIT;
    };

int main()
{

    union myAccess U;
    U.access8.lo=0xF1;
    U.access8.hi.BYTE=0x55;
    printf("%x\n",U);
    return 0;
}

这里显示编译错误

Gaurav@Gaurav-PC /cygdrive/d
$ gcc -Wall LSI.c -o LSI
LSI.c:8: error: field `hi' has incomplete type
LSI.c: In function `main':
LSI.c:33: warning: unsigned int format, myAccess arg (arg 2)
LSI.c:33: warning: unsigned int format, myAccess arg (arg 2)

我做错了什么?

【问题讨论】:

    标签: c unions


    【解决方案1】:

    在第二个例子中,当union myAccess被定义时,其字段hi的类型为union myByte,但该类型尚未定义。您需要将union myByte 的定义放在union myAccess 之前。

    【讨论】:

    • Ahh silly me.. 明白了.. 但是我在#include &lt;stdint.h&gt; 之后尝试了原型union myByte 的另一件事,但仍然出现同样的错误.. 为什么会这样?
    • @GauravK 您的代码现在看起来像这样吗:ideone.com/ttkZRB?我编译得很好。
    • 是的,工作正常.. 我在说什么.. #include &lt;stdio.h&gt; #include &lt;stdint.h&gt; union myByte; union myAccess { uint16_t access16; struct { uint8_t lo; union myByte hi;//here } access8; }; union myByte{ uint8_t BYTE; struct { ..... }BIT; }; 有什么问题我添加了联合原型;
    • @GauravK 前向声明不起作用,因为您需要一个完整的类型,您使用的是 union 本身,而不是指向它的指针。
    • 使用该代码 .. 它编译成功,但输出不正确 .. union myAccess U;U.access8.lo=0xF1;U.access8.hi.BYTE=0x55;printf("%x\n",U); 我得到 o/p $ ./LSI 612792f1 .. 它应该是 612755f1.. 怎么了?
    【解决方案2】:

    您需要先声明联合 myByte,然后再在其他 myAccess 联合中引用它。

    Working example here.

    【讨论】:

    • 我在#include &lt;stdint.h&gt; 之后尝试了原型union myByte,但仍然出现同样的错误.. 为什么会这样?
    • 我添加了一个编译成功并且运行良好的链接。仔细检查您的代码。
    • 是的,它有效.. 我是说.. 而不是先定义myByte 然后myAccess.. 如果我只是在代码的开头添加一个原型#include &lt;stdint.&gt; union myByte;.. 它不编译
    • 这是该类型的前向声明。您不能将该类型用作类/结构/联合的成员。您可以使用指向前向声明类型的引用或指针作为成员变量。 struct Foo; // forward declarationstruct Widget { Foo* goodFoo; Foo errorFoo; };
    【解决方案3】:

    在将union myByte 用作myAccess 中的struct 的成员之前,您没有声明它。编译器需要知道myByte是什么类型才能使用。

    尝试使用myByte 作为myAccess 中的类型在逻辑上等同于尝试在声明变量之前使用它:

    int main(void) {
       int a = 1, b = 1;
       c = a + b;
       int c;
       return c;
    }
    

    这将引发一个编译错误,声称 c 未声明。

    【讨论】:

      猜你喜欢
      • 2014-05-10
      • 2015-06-24
      • 1970-01-01
      • 1970-01-01
      • 2020-12-12
      • 1970-01-01
      • 2013-12-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多