CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Macro expansion problem

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

Macro expansion problem
PostPosted: Thu Apr 22, 2004 2:21 pm     Reply with quote

I think I found a compiler bug related to macro expansions. Sometimes two assembly lines are missing in the expanded code, this depends on the context and sequence of the macro being used.

I'm using PCH v3.187 on a PIC18F458.

In the following code:

Code:

#include <18F458.h>

#use delay(clock=16000000)
#fuses HS,NOWDT,OSCSEN,PUT,BROWNOUT,NOLVP


int IsLeap() {return TRUE;}

#define   YEAR_SIZE(year)   (IsLeap() ? 366 : 365)

void main()
{
  int16 foo=0;

  foo >= YEAR_SIZE(1000); // Error
  foo <= YEAR_SIZE(1000); // Error
  foo == YEAR_SIZE(1000); // Error
  foo =  YEAR_SIZE(1000); // OK
  foo += YEAR_SIZE(1000); // OK
  foo -= YEAR_SIZE(1000); // OK

  // And now the funny part
  // with the same code again.
  foo >= YEAR_SIZE(1000); // OK  !!!!
  foo <= YEAR_SIZE(1000); // OK  !!!!
  foo == YEAR_SIZE(1000); // OK  !!!!
  foo =  YEAR_SIZE(1000); // OK
  foo += YEAR_SIZE(1000); // OK
  foo -= YEAR_SIZE(1000); // OK
}


Studying the assembly code for the error lines, there are two missing instructions compared to the correct lines:

Code:

18:                  foo >= YEAR_SIZE(1000); // Error
000024    EC02     CALL 0x4, 0
000028    5201     MOVF 0x1, F, ACCESS
00002A    B4D8     BTFSC 0xfd8, 0x2, ACCESS
00002C    EF1B     GOTO 0x36

-- Missing for the error examples !!! -------
                  MOVLW 0x1
                  MOVWF 0x3, ACCESS
-------------------------------------------------

000030    0E6E     MOVLW 0x6e
000032    EF1E     GOTO 0x3c
000036    0E01     MOVLW 0x1
000038    6E03     MOVWF 0x3, ACCESS
00003A    0E6D     MOVLW 0x6d
00003C    6E01     MOVWF 0x1, ACCESS
00003E    5003     MOVF 0x3, W, ACCESS
000040    5C07     SUBWF 0x7, W, ACCESS
000042    A0D8     BTFSS 0xfd8, 0, ACCESS
000044    EF2C     GOTO 0x58
000048    A4D8     BTFSS 0xfd8, 0x2, ACCESS
00004A    EF2F     GOTO 0x5e
00004E    5001     MOVF 0x1, W, ACCESS
000050    5C06     SUBWF 0x6, W, ACCESS
000052    B0D8     BTFSC 0xfd8, 0, ACCESS
000054    EF2F     GOTO 0x5e
000058    0E00     MOVLW 0
00005A    EF2F     GOTO 0x5e
19:                  foo <= YEAR_SIZE(1000); // Error



The bug(?) only occurs for the macro's used in combination with an equation (==, <=, >=). The strange thing is that after once having used the macro in combination with an assignment (=, +=, -=) all macro's are expanding correctly.... Looks like an compiler initialization problem????

Can someone explain to me if I'm overlooking something or should I report this as a bug?


Last edited by ckielstra on Fri Apr 23, 2004 2:28 am; edited 1 time in total
RKnapp



Joined: 23 Feb 2004
Posts: 51

View user's profile Send private message

PostPosted: Thu Apr 22, 2004 7:29 pm     Reply with quote

ckielstra,

I am using PCH 3.187 (I reverted back from 3.190) on 18F8720 and have also had macro expansion problems, specifically with the ? : operator.

I am willing to admit that there is some kind of bug below that precludes these from compiling correctly, but I don't see it. These don't COMPILE, so I don't know if this is related to what you're seeing or not:

Code:

   #define    _TOGGLE(flag)    {if(flag==TRUE) flag=FALSE; else flag=TRUE;}

   // Note, for unknown reasons, these do not work:
   //#define  _TOGGLE(flag)  {(flag==TRUE)?{flag=FALSE;}:{flag=TRUE;};}
   //#define    _TOGGLE(flag)       (flag ? flag=0 : flag=1)


I would really like to know what you find out!

Have a good day,

Smile Robert
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Apr 23, 2004 1:45 am     Reply with quote

Hi Robert,

Your problem is quiet different from mine. You get compiler error messages because of grammatical errors in your code, where my program does compile without warnings but has an error in the resulting assembly code.

Comming back to your problem:
Be aware that there is a huge difference between the '?:' and the 'if-then' constructions. The first one is an operator and the second one a statement, you can not exchange these two at will. You can only use the ?: operator in situations where you normally would write a value.

Only use the ?: operator where it has a real advantage because it often makes your code harder to read, where possible use the if-then statement. I even worked for some companies that didn't allow the use of the ?: operator.

If you do insist on using the ?: operator you could have written your code like this:
Code:

#define _TOGGLE1(flag)  (flag ? (flag=0) : (flag=1))
#define _TOGGLE2(flag)  (flag==TRUE)?(flag=FALSE):(flag=TRUE)
#define _TOGGLE3(flag)  (flag ? 0 : 1)
#define _TOGGLE(flag)   {if (flag==TRUE) flag=FALSE; else flag=TRUE;}

void main()
{
  int8 flag=0;

  _TOGGLE1(flag);         // 20 bytes
  _TOGGLE2(flag);         // 18 bytes
  flag = _TOGGLE3(flag);  // 18 bytes
  _TOGGLE(flag);          // 16 bytes
}


But, as said, I prefer the if-then implementation which also turns out to result in the shortest code here. Smile



Carlo


Last edited by ckielstra on Fri Apr 23, 2004 2:05 am; edited 1 time in total
Haplo



Joined: 06 Sep 2003
Posts: 659
Location: Sydney, Australia

View user's profile Send private message

PostPosted: Fri Apr 23, 2004 2:01 am     Reply with quote

According to the version history page at:
http://www.ccsinfo.com/versions.shtml

3.189 Macro processing algorithm has been updated to meet ANSI requirements

This might be related to what you are seeing in 3.187.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Apr 23, 2004 2:32 am     Reply with quote

Version 3.187 is the latest version I have. Is there someone who can check my bug being fixed by the change in v3.189? The release note only mentions a change to meet the ANSI requirements, nothing about bug fixes....
RKnapp



Joined: 23 Feb 2004
Posts: 51

View user's profile Send private message

PostPosted: Fri Apr 23, 2004 1:46 pm     Reply with quote

ckielstra,

You have some good advice there for me. You can see that I wanted the toggle to not just fork over a true / false but actually alter the variable fed to it.

But based on your comments I'm more content with the if/then/else structure.

Thanks,

Smile Robert

ps. In past code I've used the ? : operator to deliver strings, e.g.:

Code:

   #define _SHOW_fGPS_Status(flag)\
     ((flag==GPS_NO_INPUT_RS232_)    ?    "(GPS_NO_INPUT_RS232_)" : \
      (flag==GPS_BAD_SAT_COVERAG)    ?    "(GPS_BAD_SAT_COVERAG)" : \
      (flag==GPS_SIMULATED_INPUT)    ?    "(GPS_SIMULATED_INPUT)" : \
      (flag==GPS_DATA_SANITY_ERR)    ?    "(GPS_DATA_SANITY_ERR)" : \
      (flag==GPS_SPEED_L_BOUNDED)    ?    "(GPS_SPEED_L_BOUNDED)" : \
      (flag==GPS_SPEED_LT_1_KNOT)    ?    "(GPS_SPEED_LT_1_KNOT)" : \
      (flag==GPS_SPEED_NORML_RNG)    ?    "(GPS_SPEED_NORML_RNG)" : \
      (flag==GPS_SPEED_U_BOUNDED)    ?    "(GPS_SPEED_U_BOUNDED)" : \
                                       "(CALL ROBERT KNAPP!) " )



My questions to you or anyone are:

a) where are strings like this stored? Do they take up RAM or go into ROM?

b) (I've noticed that some of my printf() stmts have tons of code so I'm wondering where their strings are stored, too.)

c) And, if I have such macros defined in a header file but do not invoke them in my code, are they tossed on the floor, or are they stuffed into RAM, too?
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon Apr 26, 2004 8:05 am     Reply with quote

a) Constant values/strings are always stored in ROM, where else are they to stay when you remove the power? When assigned to a variable, for example when initializing, the compiler might copy the value to RAM also.

b) Printf statements are known to be huge, especially the ones with difficult format-strings. Their (format)strings are constants, so stored in ROM too.

c) Any good compiler would ignore unused defines, so no storage usage.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group