LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices

Reply
 
Search this Thread
Old 05-22-2004, 09:27 PM   #1
sonajiso
Member
 
Registered: Oct 2003
Posts: 34

Rep: Reputation: 15
g++ and wrong struct member addresses / struct size misreporting


Greetings!

I have been using c++ for about two years now, but I have never run into these problems before. I create a struct (I know structs are not quite c++ but still..):

struct whatever{
unsigned char field[6];
unsigned int other;
}

Under normal circumstances, the sizeof(whatever)==10 (Given that the code is compiled for a 32-bit machine). And that would make perfect sense, and this is what I have been experiencing so far with most c++ compilers.

BUT:
In g++ for some reason, the size is reported to be 12 bytes, and the relative pointer to 'other' is 2 bytes larger than it is supposed to be once the program is ran.

Now I do not know if I missed something when I learned about unsigned chars, or I am doing something wrong now. So, please, if you have any ideas how to resolve this issue that would be greatly appreciated.

Thank you for your help in advance!
Sonajiso.
 
Old 05-22-2004, 10:13 PM   #2
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 369Reputation: 369Reputation: 369Reputation: 369
For a 32-bit processor, data is retrieved from memory in "natural" chunks of 32-bits in size. The compiler is adjusting the way your structure is stored to make memory access faster. In your other compiler, memory was organized similar to this (each row is aligned to a 32-bit boundary in memory):
Code:
Byte1       Byte2       Byte3       Byte4
----------  ----------  ----------  ----------
field[0]    field[1]    field[2]    field[3]
field[4]    field[5]    other-------other-----
other-------other       unused      unused
For the computer to access the "other" data member, it would need to do two memory fetches. The first fetch would get the first half of the field (in the 32-bit location shared with field[4] and field[5]), and the second fetch would get the remaining half. Then the processor would have to do some bit-wise shifting and bitwise ORing to get the real value. What g++ did is this:
Code:
Byte1       Byte2       Byte3       Byte4
----------  ----------  ----------  ----------
field[0]    field[1]    field[2]    field[3]
field[4]    field[5]    unused      unused
other-------other-------other-------other
By adding two bytes worth of "buffer", the compiler has now made the "other" member aligned to a 32-bit boundary. That means the computer can access that data in a single memory fetch.

So, that's why sizeof(whatever) reports 12 bytes (those two unused bytes are implicitly included), and it's also why the address of "other" is 2 bytes different from your other compilers.

Now, if you don't like this, there's a compiler directive to prevent this behavior. It's something like __PACKED. I forget exactly what it is, but unless you're going to have a data set so huge that you're worried about using all of your available memory, then it's not worth your time to hunt it down.
 
Old 05-22-2004, 10:30 PM   #3
sonajiso
Member
 
Registered: Oct 2003
Posts: 34

Original Poster
Rep: Reputation: 15
Greetings, Dark_Helmet!

First, I would like to thank you for the prompt and very descriptive response! I greatly appreciate your help since now I know what exactly causes the slight misalignments I experience.

So, as I understand, the compiler tries to (by default) optimize code for access time even if that means the loss of a couple of bytes. That I would completely understand and probably even prefer normally, but in the case of this program, the struct's members would have to be at -exact- offsets -the program must modify/access already existing records in a file, and for this reason I cannot afford the offsets to be messed with by the compiler.

So I guess, I will have to look into g++ man's to see if this optimization could be disabled somehow, or perhaps I would even have to re-learn c++...



Again, thank Thank you for your explanation.
Sonajiso.
 
Old 05-22-2004, 10:45 PM   #4
sonajiso
Member
 
Registered: Oct 2003
Posts: 34

Original Poster
Rep: Reputation: 15
P.S.:

In the meantime, I did some research, and I found that in g++ struct's can be forced to be packed by adding __attribute__((packed)) in the declaration, for example

Code:
struct __attribute__((packed)) astruct{
   char field[6];
   unsigned int other;
};
Please refer to <http://gcc.gnu.org/ml/gcc-bugs/1999-02n/msg00635.html> for the original post about g++ and packed structures.
 
Old 05-22-2004, 11:00 PM   #5
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 369Reputation: 369Reputation: 369Reputation: 369
I'm glad I was able to help out some. I'm assuming that you're back on track now with the packed attribute?

I had to deal with this before, so I know it can be a pain in the butt; especially if it's the first time it rears is ugly head.
 
Old 05-22-2004, 11:16 PM   #6
sonajiso
Member
 
Registered: Oct 2003
Posts: 34

Original Poster
Rep: Reputation: 15
The __attribute__((packed)) did fix the alignment problems in structs I was describing earlier (to my relief, to say the least). Thanks to your guidance, I am back on track once again with this program.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
struct member alignment wmoti Programming 2 10-10-2005 06:24 AM
About struct size Nerox Programming 3 02-07-2005 05:49 PM
switch statement converting struct char to struct int oceaneyes2 Programming 2 12-10-2003 05:30 PM
using struct type X as pointer in struct X. worldmagic Programming 1 10-28-2003 03:06 PM
Accessing a struct inside struct cxel91a Programming 1 09-17-2003 05:24 PM


All times are GMT -5. The time now is 07:49 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration