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

Problem with structure size

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



Joined: 11 Jan 2006
Posts: 21
Location: Quebec (Canada)

View user's profile Send private message Visit poster's website

Problem with structure size
PostPosted: Fri Jan 28, 2011 2:49 pm     Reply with quote

Hello,

I've been having problems with structures lately, and found that the size of my structures are not giving what I expected. To simplify my problem, I've written the following program:

Code:

void main (void)

   unsigned int16 size;
   
   struct _diskinfo
   {
      char   jmpBoot[3];
      char   OEMName[8];
      unsigned int16  BytsPerSec;
      char   SecPerClus;
      unsigned int16  RsvdSecCnt;
      char   NumFATs;
      unsigned int16  RootEntCnt;
      unsigned int16  TotSec16;
      char   Media;
      unsigned int16  FATSz16;
      unsigned int16  SecPerTrk;
      unsigned int16  NumHeads;
      unsigned int32  HiddSec;
      unsigned int32  TotSec32;
   } fDiskInfo;
   
   size = sizeof(fDiskInfo);
   
   fprintf(PC,"Size = %u\r\n",size);
   while(1);
}


The size printed is 40.
This is confirmed from the list file:
Code:

....................    size = sizeof(fDiskInfo);
00BB4:  MOV     #28,W4
00BB6:  MOV     W4,2FE6

And from the .sym:
Code:

2FE6-2FE7 main.size
2FE8-300F main.fDiskInfo


But from my calculation it should be the following:
7*2(int16) + 2*4(int32) + 14*1(char) = 36 Confused

What is it I'm not getting?

I'm using a 33FJ256GP710 and compile with the latest version 4.118.

I'm new with 16 bit parts, so there may be something I'm not getting. Embarassed

Thanks in advance,

Ben
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jan 28, 2011 3:05 pm     Reply with quote

It's possible that the compiler is padding the elements to 'int16' size.
It may also pad the whole structure out to a mulitple of 'int32'.
It's common for compilers (such as MSVC++) to do this. I don't see
a "pragma pack" option in the PCD manual which would let you control
the packing. Or it could be a bug. You could investigate if it's a packing
issue with the offsetof() function to display the offsets of the individual
structure elements.
Benjamin



Joined: 11 Jan 2006
Posts: 21
Location: Quebec (Canada)

View user's profile Send private message Visit poster's website

PostPosted: Fri Jan 28, 2011 3:27 pm     Reply with quote

Thanks! You're right. The compiler does "pad" the elements to 'int16' size.

offsetof(fDiskInfo,BytsPerSec); returns 12. So the compiler adds a byte after OEMName and probably adds one after each 'char' after this which explains the 4 extra bytes.

I understand why the compiler would do this, but this is a little problematic since the structures must respect the byte pattern of some specs which I cannot change (as in FAT32 and others). I'm porting a program from an 8bit PIC to 16 bits and I have a dozen structures like this one.

There must be a way of deactivating this? I haven't checked the doc for this yet and will be doing that on Monday. But if anyone has an answer till than it would be appreciated.

Thanks.
Benjamin



Joined: 11 Jan 2006
Posts: 21
Location: Quebec (Canada)

View user's profile Send private message Visit poster's website

PostPosted: Wed Feb 09, 2011 10:07 am     Reply with quote

Here's an update in case someone else runs into the same problem.

The CCS manual does mention that the compiler will align 16 bit fields in a structure to even bytes.

And when asked if it is possible to avoid this, here's the response from CCS:

Quote:

Yes, you can use the GCC attribute for this.

It looks like this:

struct __attribute__((packed))
{
uint8_t a_0;
uint16_t a_12;
uint8_t a_3;
uint8_t a_4;
uint16_t a_56;
uint8_t a_7;
uint16_t a_89;
uint8_t a_a;
};

I would refer to the GCC manual for more info.

It is relatively new to the compiler, that is why it's not documented yet.

You also have to be careful using it, because addressing a word pointer if it's not word aligned will cause address failure on a 16bit PIC. This should only happen if you manually created a pointer to an individual entry in the structure, which according to many C purists is bad code design.



I haven't tested it yet, but this should fix my problems.

Benjamin
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