473,385 Members | 2,004 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Size of a struct - totally confused

I'm pretty sure this is non-totally-trivial enough and standard-C++ enough
to post here, however much it may initially look like a "how do I make a
computer game?" question, though I may be wrong.

I'm loading a bitmap, and as I'm using Linux I've had to define
BITMAPFILEHEADER myself (maybe better practice would be to give my version
a new name or whatever, I dunno). Windows uses WORDs and DWORDs to
define it, I've used some standard-size types provided by SDL (a
graphics/sound library thing) to define it thus:

struct BITMAPFILEHEADER
{
Uint16 bfType;
Uint32 bfSize;
Uint16 bfReserved1;
Uint16 bfReserved2;
Uint32 bfOffBits;
};

For some reason I utterly can't fathom, however, a debugger shows that my
bitmap loader function believes that sizeof(BITMAPFILEHEADER) == 16.

Surely that should be 14?

I then tried redefining it a couple of times:

BITMAPFILEHEADER
{
Uint32 bfType; //changed from 16 to 32
Uint32 bfSize;
Uint16 bfReserved1;
Uint16 bfReserved2;
Uint32 bfOffBits;
};

This gives sizeof(BITMAPFILEHEADER) == 16, which is now correct.

BITMAPFILEHEADER
{
Uint32 bfType;
Uint32 bfSize;
Uint32 bfReserved1;
Uint32 bfReserved2;
Uint32 bfOffBits;
};

This gives sizeof(BITMAPFILEHEADER) == 20, which is also correct.

Most likely I just misunderstand something somewhere, but I've no idea
what.

Thanks,

James
Jul 22 '05 #1
11 2259
James Gregory wrote:
I'm pretty sure this is non-totally-trivial enough and standard-C++
enough to post here, however much it may initially look like a "how do I
make a computer game?" question, though I may be wrong.

I'm loading a bitmap, and as I'm using Linux I've had to define
BITMAPFILEHEADER myself (maybe better practice would be to give my
version a new name or whatever, I dunno). Windows uses WORDs and DWORDs
to
define it, I've used some standard-size types provided by SDL (a
graphics/sound library thing) to define it thus:

struct BITMAPFILEHEADER
{
Uint16 bfType;
Uint32 bfSize;
Uint16 bfReserved1;
Uint16 bfReserved2;
Uint32 bfOffBits;
};

For some reason I utterly can't fathom, however, a debugger shows that my
bitmap loader function believes that sizeof(BITMAPFILEHEADER) == 16.

Surely that should be 14?

[SNIP]

Not necessarily:

bfType: 2
Padding to get bfSize to start again on int boundary: 2
bfSize: 4
Res1: 2
Res2: 2
bfOffBits: 4

That is 16. You may want to look at the gcc/g++ docs how to ask packing for
a struct.

--
WW aka Attila
:::
Be bold in what you stand for and careful what you fall for.
Jul 22 '05 #2
"James Gregory" <ja****@f2s.com> wrote...
I'm pretty sure this is non-totally-trivial enough and standard-C++ enough
to post here, however much it may initially look like a "how do I make a
computer game?" question, though I may be wrong.

I'm loading a bitmap, and as I'm using Linux I've had to define
BITMAPFILEHEADER myself (maybe better practice would be to give my version
a new name or whatever, I dunno). Windows uses WORDs and DWORDs to
define it, I've used some standard-size types provided by SDL (a
graphics/sound library thing) to define it thus:

struct BITMAPFILEHEADER
{
Uint16 bfType;
Uint32 bfSize;
Uint16 bfReserved1;
Uint16 bfReserved2;
Uint32 bfOffBits;
};

For some reason I utterly can't fathom, however, a debugger shows that my
bitmap loader function believes that sizeof(BITMAPFILEHEADER) == 16.

Surely that should be 14?

I then tried redefining it a couple of times:

BITMAPFILEHEADER
{
Uint32 bfType; //changed from 16 to 32
Uint32 bfSize;
Uint16 bfReserved1;
Uint16 bfReserved2;
Uint32 bfOffBits;
};

This gives sizeof(BITMAPFILEHEADER) == 16, which is now correct.

BITMAPFILEHEADER
{
Uint32 bfType;
Uint32 bfSize;
Uint32 bfReserved1;
Uint32 bfReserved2;
Uint32 bfOffBits;
};

This gives sizeof(BITMAPFILEHEADER) == 20, which is also correct.

Most likely I just misunderstand something somewhere, but I've no idea
what.


Sizes of object can include so called "padding" to ensure that the objects
in an array begin at a particular multiple of bytes boundary. For example,
on some platforms it should be multiple of 4 to make memory access faster.
14 is not multiple of 4, so it chooses the next larger multiple of 4.

There probably is a [compiler-specific] way to control the padding or the
alignment factor, consult your compiler documentation to find out how to
do that.

Victor
Jul 22 '05 #3
James Gregory wrote:
I'm pretty sure this is non-totally-trivial enough and standard-C++ enough
to post here, however much it may initially look like a "how do I make a
computer game?" question, though I may be wrong.
Relax - padding is on-topic.
I'm loading a bitmap, and as I'm using Linux I've had to define
BITMAPFILEHEADER myself (maybe better practice would be to give my version
a new name or whatever, I dunno).
There must be a graphics library you can use. Start with ImageMagick.
Windows uses WORDs and DWORDs to
define it, I've used some standard-size types provided by SDL (a
graphics/sound library thing) to define it thus:

struct BITMAPFILEHEADER
{
Uint16 bfType;
Uint32 bfSize;
Uint16 bfReserved1;
Uint16 bfReserved2;
Uint32 bfOffBits;
};

For some reason I utterly can't fathom, however, a debugger shows that my
bitmap loader function believes that sizeof(BITMAPFILEHEADER) == 16.

Surely that should be 14?


Plenty of hardware works best reading integers aligned on quad-word
boundaries. Put another way, the address of a bfSize can evenly divide by 4
with 0 remainder.

The compiler inserted an invisible 16-bit padding element between bfType and
bfSize. Compilers are allowed to do this, and required to give notice how
they do it. It's "implementation specified".

Now ask the documentation or forum that covers your compiler how to turn it
off. They will probably point out a library that already reads BMP files,
too.

--
Phlip
http://www.xpsd.org/cgi-bin/wiki?Tes...UserInterfaces
Jul 22 '05 #4
James Gregory wrote:
I'm pretty sure this is non-totally-trivial enough and standard-C++
enough to post here, however much it may initially look like a "how do
I make a computer game?" question, though I may be wrong.

I'm loading a bitmap,
You mean a .bmp file? The term "bitmap" has a different meaning outside
the Microsoft world.
and as I'm using Linux I've had to define BITMAPFILEHEADER myself
(maybe better practice would be to give my version a new name or
whatever, I dunno). Windows uses WORDs and DWORDs to define it, I've
used some standard-size types provided by SDL (a graphics/sound
library thing) to define it thus:

struct BITMAPFILEHEADER
{
Uint16 bfType;
Uint32 bfSize;
Uint16 bfReserved1;
Uint16 bfReserved2;
Uint32 bfOffBits;
};

For some reason I utterly can't fathom, however, a debugger shows that
my bitmap loader function believes that sizeof(BITMAPFILEHEADER) ==
16.
What do you mean by "believes"?
Surely that should be 14?
Nope. You seem to be getting alignment. For faster access (and on many
hardware platforms for being able to access it at all), 32bit variables
are often alinged on a 32bit basis. So your compiler probably added two
bytes of empty space between the first and second member to align it.
I then tried redefining it a couple of times:

BITMAPFILEHEADER
{
Uint32 bfType; //changed from 16 to 32
Uint32 bfSize;
Uint16 bfReserved1;
Uint16 bfReserved2;
Uint32 bfOffBits;
};

This gives sizeof(BITMAPFILEHEADER) == 16, which is now correct.

BITMAPFILEHEADER
{
Uint32 bfType;
Uint32 bfSize;
Uint32 bfReserved1;
Uint32 bfReserved2;
Uint32 bfOffBits;
};

This gives sizeof(BITMAPFILEHEADER) == 20, which is also correct.

Most likely I just misunderstand something somewhere, but I've no idea
what.


The above shows one reason why it's never a good idea to read binary
data directly into a struct. It's not portable. Also think what happens
if your program will be compiled e.g. on linux/ppc. Your program will
stop to work because of endianness problems. And as I wrote above, some
systems can't even access unaligned memory. So better read each value
separately, and if you want portability, consider things like
endianness conversion.

Jul 22 '05 #5
James Gregory wrote:
....
For some reason I utterly can't fathom, however, a debugger shows that my
bitmap loader function believes that sizeof(BITMAPFILEHEADER) == 16.

Surely that should be 14?


So many people have already answered why it's not. However - try this:

#pragma pack(1)
struct BITMAPFILEHEADER
{
Uint16 bfType;
Uint32 bfSize;
Uint16 bfReserved1;
Uint16 bfReserved2;
Uint32 bfOffBits;
};
#pragma pack()

The "pack" pragma is not standard but I have yet to meet a compiler that
does not implement it (in some way).

....

Jul 22 '05 #6
James Gregory wrote:
For some reason I utterly can't fathom, however, a debugger shows that my
bitmap loader function believes that sizeof(BITMAPFILEHEADER) == 16.

Surely that should be 14?

http://www.eskimo.com/~scs/C-faq/q2.13.html

Brian Rodenborn
Jul 22 '05 #7
James Gregory wrote:
I'm pretty sure this is non-totally-trivial enough and standard-C++ enough
to post here, however much it may initially look like a "how do I make a
computer game?" question, though I may be wrong.

I'm loading a bitmap, and as I'm using Linux I've had to define
BITMAPFILEHEADER myself (maybe better practice would be to give my version
a new name or whatever, I dunno). Windows uses WORDs and DWORDs to
define it, I've used some standard-size types provided by SDL (a
graphics/sound library thing) to define it thus:

#include<stdint.h>
struct BITMAPFILEHEADER {
uint16_t bfType;
uint32_t bfSize;
uint16_t bfReserved1;
uint16_t bfReserved2;
uint32_t bfOffBits;
};

For some reason I utterly can't fathom, however, a debugger shows that my
bitmap loader function believes that sizeof(BITMAPFILEHEADER) == 16.

Surely that should be 14?


Apparently, your compiler and/or machine architecture
requires unint32_t alignment on 32 bit word boundaries.

Try this:

struct X {
int i;
double x;
int j;
};

and this:

struct Y {
double x;
int i;
int j;
};

A double probably requires a 64 bit word alignment.

If this is important to you, you should try place the objects
with the coarsest alignment requirements first.

Jul 22 '05 #8
On Fri, 30 Jan 2004 23:50:33 GMT, "Phlip" <ph*******@yahoo.com> wrote
in comp.lang.c++:

[snip]

Plenty of hardware works best reading integers aligned on quad-word
boundaries. Put another way, the address of a bfSize can evenly divide by 4
with 0 remainder.

The compiler inserted an invisible 16-bit padding element between bfType and
bfSize. Compilers are allowed to do this, and required to give notice how
they do it. It's "implementation specified".


Both the C and C++ standards define the term "implementation-defined",
not "implementation specified". And both spell it with the hyphen.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Jul 22 '05 #9
On Fri, 30 Jan 2004 16:07:58 -0800, "E. Robert Tisdale"
<E.**************@jpl.nasa.gov> wrote in comp.lang.c++:
James Gregory wrote:
I'm pretty sure this is non-totally-trivial enough and standard-C++ enough
to post here, however much it may initially look like a "how do I make a
computer game?" question, though I may be wrong.

I'm loading a bitmap, and as I'm using Linux I've had to define
BITMAPFILEHEADER myself (maybe better practice would be to give my version
a new name or whatever, I dunno). Windows uses WORDs and DWORDs to
define it, I've used some standard-size types provided by SDL (a
graphics/sound library thing) to define it thus:


#include<stdint.h>


Non standard in C++. Be all right if you were posting in comp.lang.c,
though.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Jul 22 '05 #10
On Fri, 30 Jan 2004 23:29:26 +0000, James Gregory wrote:
This gives sizeof(BITMAPFILEHEADER) == 20, which is also correct.

Most likely I just misunderstand something somewhere, but I've no idea
what.

Thanks,


Wow, thanks for all the replies, most helpful.

James
Jul 22 '05 #11
The compiler is adding pad bytes. The following article will help:

http://www.eventhelix.com/RealtimeMa...ndOrdering.htm

Sandeep
--
http://www.EventHelix.com/EventStudio
EventStudio 2.0 - System Architecture Design CASE Tool
Jul 22 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
by: newbiecpp | last post by:
C++ standard says that a reference is not a object. My question is a reference has size? int myInt; int& myRef = myInt; myRef is just another name of myInt? My confusion is that if myRef is...
6
by: someone | last post by:
I have *thought* that setjmp/longjmp() should take a pointer to jmp_buf. And the calling function should hold the actual struct data. But ... I trid on both Win32 and Linux, it seems that...
15
by: puzzlecracker | last post by:
Got Confused on the interview with memory alligment questions... PLEASE HELP -- How much bytes of memory will structs below take on 32 bit machine? What about 64 bit machine? Why is it different?...
7
by: venkatbo | last post by:
Hi folks, Of TurboGers & Django WAF candidates, which one would be easier to use in an environment where the data/content doesn't come an RDBMS, but from other server-side apps... If these are...
2
by: Michael Yanowitz | last post by:
Hello: I am relatively new to Python and this is my first post on this mailing list. I am confused as to why I am getting size differences in the following cases: >>> print...
10
by: Giovanni Bajo | last post by:
Hello, given the ongoing work on struct (which I thought was a dead module), I was wondering if it would be possible to add an API to register custom parsing codes for struct. Whenever I use it...
17
by: djcredo | last post by:
Hey all, I want to return a pointer to a struct. Here is what I'lm trying to do: struct Position{ int x; int y; }; Position* GraphicTag::getRenderCentre(){
9
by: herobeat | last post by:
Hi all, I'm having a hell of a time with declaring a struct to hold some binary data I'm trying to read from some files on disk. What I would like to do is something like this: public struct...
42
by: Jeff P. Syverson | last post by:
Can anyone tell me the best way to find out the size of a struct, without using the sizeof function? I'm currently thinking of: struct foo s; int size_of_foo = (char *)&s - (char *)s; but is...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.