View previous topic :: View next topic |
Author |
Message |
forgie
Joined: 03 Nov 2005 Posts: 7
|
Comparing Structs |
Posted: Sat Nov 05, 2005 9:59 am |
|
|
Hi there.
There's most likely a simple solution to my problem, and I'm hoping someone can enlighten me to it. I have two structs of the same type, and I want to compare them. I have one called State, and one called Old_State. I was hoping that
#define State_Changed (State != Old_State)
then later on
if(State_Changed) Do_Blah();
would do the trick as a comparison, but PICC says "A numeric expression must appear here"
Any ideas?
Thanks |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
forgie
Joined: 03 Nov 2005 Posts: 7
|
|
Posted: Sat Nov 05, 2005 12:01 pm |
|
|
Yeah, I was thinking more along the lines of comparing the block of memory. I just don't know how to, that's all.
I would've thought you could just write:
if((int32) State != (int32) Old_State) Something_Changed();
But it doesn't work as expected..... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
forgie
Joined: 03 Nov 2005 Posts: 7
|
|
Posted: Sat Nov 05, 2005 8:39 pm |
|
|
Thanks PCM Programmer. I guess I didn't think about the 'padding bits.' If, however, I make my struct so that it takes up exactly 4 bytes (it's currently 3 bytes and 2 bits, so it should be pretty easy to pad it), is there any reason I couldn't compare them how I suggested previously? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Nov 05, 2005 9:53 pm |
|
|
I didn't realize your structure was only four bytes long. In that case
it would work. Though if you look at the following test program
the standard approach of element by element comparison produces
exactly the same ASM code as casting the structures to int32 and
comparing them. I tend to do things in the standard way for reasons
of safety and future maintainability of the code.
Code: | #include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
typedef struct
{
int8 a;
int8 b;
int16 c;
}T_ABC;
T_ABC struct1;
T_ABC struct2;
//=================================
void main()
{
int result;
if((int32)struct1 == (int32)struct2)
result = 1;
else
result = 0;
if((struct1.a == struct2.a) &&
(struct1.b == struct2.b) &&
(struct1.c == struct2.c))
result = 1;
else
result = 0;
while(1);
} |
Listing for int32 method:
Code: |
0000 ... if((int32)struct1 == (int32)struct2)
0014 0825 00322 MOVF 25,W
0015 0221 00323 SUBWF 21,W
0016 1D03 00324 BTFSS 03.2
0017 2827 00325 GOTO 027
0018 0826 00326 MOVF 26,W
0019 0222 00327 SUBWF 22,W
001A 1D03 00328 BTFSS 03.2
001B 2827 00329 GOTO 027
001C 0827 00330 MOVF 27,W
001D 0223 00331 SUBWF 23,W
001E 1D03 00332 BTFSS 03.2
001F 2827 00333 GOTO 027
0020 0828 00334 MOVF 28,W
0021 0224 00335 SUBWF 24,W
0022 1D03 00336 BTFSS 03.2
0023 2827 00337 GOTO 027
|
Listing for standard method:
Code: |
0000 ... if((struct1.a == struct2.a) &&
0000 ... (struct1.b == struct2.b) &&
0000 ... (struct1.c == struct2.c))
0028 0825 00350 MOVF 25,W
0029 0221 00351 SUBWF 21,W
002A 1D03 00352 BTFSS 03.2
002B 283B 00353 GOTO 03B
002C 0826 00354 MOVF 26,W
002D 0222 00355 SUBWF 22,W
002E 1D03 00356 BTFSS 03.2
002F 283B 00357 GOTO 03B
0030 0827 00358 MOVF 27,W
0031 0223 00359 SUBWF 23,W
0032 1D03 00360 BTFSS 03.2
0033 283B 00361 GOTO 03B
0034 0828 00362 MOVF 28,W
0035 0224 00363 SUBWF 24,W
0036 1D03 00364 BTFSS 03.2
0037 283B 00365 GOTO 03B
|
|
|
|
forgie
Joined: 03 Nov 2005 Posts: 7
|
|
Posted: Sat Nov 05, 2005 10:10 pm |
|
|
Ok, that's good to know. I'll try padding the struct and comparing them.... although this is all becoming a bit unwieldy for the purposes that I had envisaged the struct being useful for in the first place! Such is life... |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Sun Nov 06, 2005 12:13 pm |
|
|
Is it possible to declare a union with your struct and an int32? If it is, then your int32 and the union will both reside in the same 4 bytes in RAM. Comparing two structs is then replaced by comparing two int32's.
I have no idea if this will work - it's just a suggestion. |
|
|
|