A89: Re: Re: What is wrong here?
[Prev][Next][Index][Thread]
A89: Re: Re: What is wrong here?
Hi!
>> 1) missing braces around initializer for '(anonymous).xy'
>
> This is not an error, but a warning. It is thrown because
> SCR_RECT is a union. To get rid of it, just put the extra
> braces in (double braces around the initializer). If it
> shows as an error or doesn't compile, please give me some
> additional information (e.g. using IDE or command-line
> compiler, version of TI-GCC, ...)
Yes. This is somewhat my error guilt too. As I compiled my
first programs without -Wall option, I never received this
warning, so I didn't noticed that extra braces are necessary.
That's why a lot of my programs and examples in the documentation
are with only one braces, so it produce a confusion. I must
rewrite the documentation to correct this.
>> 2) invalid lvalue in unary '&'
>
> Well, you already know the solution for that: The initializers
> can only be constants (I think).
No, initializers may be non-constants (in GNU C, but TIGCC is GNU C).
For example,
int a=3,b=4,c=5,d=6;
SCR_RECT myScr={b+a,b-a,d+c,d-c};
is quite legal. The problem is much more complex. GNU C has one
extension in addition to ordinary C: cast constructors. This is a
method for constructing structures, arrays, unions etc. "on fly" by
using a typecasting an initializer to appropriate data type, for
example
(SCR_RECT){{10,10,50,50}}
So, you can use
SCR_RECT myScr;
...
myScr=(SCR_RECT){{10,10,50,50}};
which is impossible in ordinary C (ANSI C). You can even use
myScr=(SCR_RECT){{a,b,c,d}};
where a,b,c,d are expressions. Well, but what is now the problem?
See, C has two type of objects: lvalues and non-lvalues. lvalues
are objects which may appear on the left size of an assignment.
For example, a variable is a lvalue and a constant is not a lvalue,
because x=5 is legal and 5=x (or 5=3) is not legal. Not only
variables are lvalues; for example, dereferenced pointers are also
lvalues, so this is legal for example (store 100 at address 0x4c00):
*(char*)0x4c00=100;
So, *(char*)0x4c00 is a lvalue. Now, about the problem. In GNU C,
cast constructors are lvalues only if the initializer is completely
constant. I.e. (SCR_RECT){{10,10,50,50}} is a lvalue, but
(SCR_RECT){{a,b,c,d}} is not. As C language accepts unary "&"
operator (i.e. "address of") only on lvalue objects, this means
that, for example,
&(SCR_RECT){{10,10,50,50}}
is legal, but
&(SCR_RECT){{a,b,c,d}}
is not! This is the real cause of the problem!!!
What you can do? Declare one SCR_RECT variable, say myScr,
SCR_RECT myScr;
and instead of
ScrRectFill(&(SCR_RECT){0,first_y,SCREEN_WIDTH,first_y+16},ScrRect,A_XOR);
use:
myScr=(SCR_RECT){{0,first_y,SCREEN_WIDTH,first_y+16}};
ScrRectFill(&myScr,ScrRect,A_XOR);
Note that &myScr is legal, because myScr is a lvalue (it is an ordinary
variable).
I hope that this helps a lot understanding of cast constructors and
lvalues.
Cheers,
Zeljko Juric