0

Consider below code, I have written:

#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;
}

The output is:

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

Now when I modify my code as below:

#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;
}

It is showing compilation error at here

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)

What am I doing wrong?

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Gaurav K
  • 2,864
  • 9
  • 39
  • 68

3 Answers3

2

In the second example, when union myAccess is defined, its field hi has type union myByte, but that type is not defined yet. You need to put the definition of union myByte before union myAccess.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
  • Ahh silly me.. got it.. But one more thing I tried prototype `union myByte` just after `#include ` , but still got same error .. why so? – Gaurav K Mar 07 '14 at 02:11
  • @GauravK Does your code now look like this: http://ideone.com/ttkZRB ? Compiles fine by me. – Yu Hao Mar 07 '14 at 02:17
  • Yes that works fine.. What I am saying .. what is wrong with `#include #include union myByte; union myAccess { uint16_t access16; struct { uint8_t lo; union myByte hi;//here } access8; }; union myByte{ uint8_t BYTE; struct { ..... }BIT; };` I have added a prototype for union; – Gaurav K Mar 07 '14 at 02:21
  • 1
    @GauravK Forward declaration won't work because you need a complete type here, you are using the `union` itself, not a pointer to it. – Yu Hao Mar 07 '14 at 02:25
  • With that code .. It compiles successfully but output is not correct .. `union myAccess U;U.access8.lo=0xF1;U.access8.hi.BYTE=0x55;printf("%x\n",U);` I am getting o/p `$ ./LSI 612792f1 ` .. it should have been `612755f1`.. what is wrong? – Gaurav K Mar 07 '14 at 02:34
  • @GauravK That's a different question, try debug it yourself first. – Yu Hao Mar 07 '14 at 02:38
2

You need to declare the union myByte before you reference it within your other myAccess union.

Working example here.

NickC
  • 385
  • 1
  • 10
  • I tried prototype `union myByte` just after `#include ` , but still got same error .. why so? – Gaurav K Mar 07 '14 at 02:14
  • I added a link that compiles successfully and runs fine. Double check your code. – NickC Mar 07 '14 at 02:23
  • Yes it works.. I am saying .. instead of first defining `myByte` and then `myAccess`.. what if I just add a prototype at the start of code `#include union myByte;`.. it does not compile – Gaurav K Mar 07 '14 at 02:26
  • That is a forward declaration for the type. You cannot use that type as a member of a class/struct/union. You can use a reference or pointer to a forward declared type as a member variable. `struct Foo; // forward declaration` `struct Widget { Foo* goodFoo; Foo errorFoo; };` – NickC Mar 07 '14 at 14:33
0

You are not declaring the union myByte before using it in as a member of the struct in myAccess. The compiler needs to know what is the type myByte before it can be used.

Trying to use myByte as type in myAccess is logically equivalent as trying to use a variable before declaring it:

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

This will throw a compilation error claiming that c is undeclared.

juan.facorro
  • 9,791
  • 2
  • 33
  • 41