"jlara" <jl***@wowway.com> writes:
[...]
The compiler gives the error "request for member 'bit' in something not
a structure or union" for the following code:
/************************************************** *
* TIOS : Timer input capture/output compare select
************************************************** **/
typedef union
{
uint8 byte;
struct
{
uint8 ios0 : 1;
uint8 ios1 : 1;
uint8 ios2 : 1;
uint8 ios3 : 1;
uint8 ios4 : 1;
uint8 ios5 : 1;
uint8 ios6 : 1;
uint8 ios7 : 1;
}bit;
}tTIOS;
#define tios *(tTIOS volatile *)(C_REG_BASE_ADDR + 0x040u)
That is the jist of my original post. After struggling with this error
and not understanding the reason, I changed the macro definition to the
following and the compiler was fine with it:
#define tios (*(tTIOS volatile *)(C_REG_BASE_ADDR + 0x040u))
I am confused as to why. I would appreciate any insight into this and
thanks a lot in advance.
Macro expansion doesn't work with expressions, it works with sequences
of tokens. The token sequence is interpreted in the context of the
expansion, not in the context of the definition.
It's not at all surprising that a macro definition that's not enclosed
in parentheses would cause problems. Take a look at my previous reply
for an example (the SIX*NINE program). Compile and run the program,
see what output it produces, and understand why it behaves the way it
does. Think about what the the printf statement will look like after
the macros are expanded.
The compiler is not complaining about the macro definition. The only
requirement there is that the expansion needs to be a valid token
sequence. You don't even have to have matched parentheses; the following
would be a perfectly legal macro definition:
#define FOO (*(tTIOS volatile *)(C_REG_BASE_ADDR + 0x040u
The compiler is complaining about an invocation of the macro. Since
you didn't show us either the invocation or the definition of
C_REG_BASE_ADDR, we have no way to guess specifically what the problem
is. But since you have the actual code in front of you, I encourage
you to try to figure this out for yourself. I think you have enough
information to do so. If you get stuck, feel free to post again.
A couple of minor points:
As I mentioned before, macro names are conventionally all-caps; TIOS
would be a better name for your macro that tios. Lower-case macro
names are perfectly legal, of course; this is just a style issue.
The only portable types for bit fields are int, signed int, and
unsigned int (and _Bool in C99); plain int can be treated as either
signed or unsigned. Declaring bit fields of type uint8 is
non-portable, both for the reasons above and because there's no
standard type called uint8. If your compiler or your program provides
a uint8 type (probably a typedef for unsigned char), and your compiler
supports uint8 bit fields as an extension, *and* if declaring the bit
fields as uint8 actually gives you something that declaring them as
unsigned int wouldn't, that's fine.
--
Keith Thompson (The_Other_Keith)
ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.