padding

This is a discussion on padding within the C++ Programming forums, part of the General Programming Boards category; If I write a structure (or class) like Code: struct rvBitmap { //fileheader follows (14 bytes): unsigned char magic1; // ...

  1. #1
    Registered User
    Join Date
    Feb 2003
    Posts
    595

    padding

    If I write a structure (or class) like
    Code:
    struct rvBitmap {
      //fileheader follows (14 bytes):
      unsigned char  magic1;    // Magic number 'BM'     2 bytes
      unsigned char  magic2;
      unsigned int   fileSize;  //                       4 bytes
      unsigned short res1;      // Reserved (0)          2 bytes
      unsigned short res2;      // Reserved (0)          2 bytes
      unsigned int   offset;    // Offset to image data  4 bytes
      //infoheader follows (40 bytes):
      unsigned int   infoSize;     // infoheader size    4 bytes
      int            imgWidth;     //                    4 bytes
      int            imgHeight;    //                    4 bytes
      unsigned short planes;       //                    2 bytes
      unsigned short bitsPerPixel; //                    2 bytes
      unsigned int   compression;  //                    4 bytes
      unsigned int   imgSize;      //                    4 bytes
      int            xResolution;  //                    4 bytes
      int            yResolution;  //                    4 bytes
      unsigned int   nColors;      //                    4 bytes
      unsigned int   nImportant;   //                    4 bytes
      
      vector<unsigned char> pixels;
    
      ...[constructors & other methods]
    }
    can I safely make any assumptions about whether, where, and how much padding will be added?

    For example, can I assume that the 40 bytes beginning with infoSize and ending with nImportant will be contiguous in memory?

    Are there general rules about this, or is it all compiler- or OS-specific?
    Last edited by R.Stiltskin; 01-31-2009 at 11:52 AM.

  2. #2
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Katy, Texas
    Posts
    2,309
    You can make any assumption you want, if you are willing to accept the consequences of a wrong assumption!!

    It's quite easy to figure out where padding, if any, is taking place. (and it is in your example)

    At compile time, you can use the offsetOf and sizeOf preprocessor directives to determine if any padding is happening. And at runtime, you can do the same thing by using sizeOf and calculating addresses of the elements.

    For instance...

    if sizeOf(magic1) + offsetOf(magic1) == offsetOf(magic2) then no padding.

    Or, maybe better, assert(....)
    Mac and Windows cross platform programmer. Ruby lover.

    Quote of the Day
    12/20: Mario F.:I never was, am not, and never will be, one to shut up in the face of something I think is fundamentally wrong.

    Amen brother!

  3. #3
    Registered User
    Join Date
    Feb 2003
    Posts
    595
    Quote Originally Posted by Dino View Post
    You can make any assumption you want, if you are willing to accept the consequences of a wrong assumption!!
    Haha! That's the point.

    I was just wondering if I could safely be "cute" & write something like
    Code:
    stream.read( (char*)&infosize, 40 );
    rather than read in each value separately. If you're telling me this is implementation-specific, it's easier to simply read in the fields individually than to test.

  4. #4
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Katy, Texas
    Posts
    2,309
    Assuming (there's that word again) you work out your intended offsets, and you keep everything relative to each other, and the file was written on the machine that reads it, you should be alright. In other words, don't use a hardcoded value like "40", but calculate the length at runtime.
    Mac and Windows cross platform programmer. Ruby lover.

    Quote of the Day
    12/20: Mario F.:I never was, am not, and never will be, one to shut up in the face of something I think is fundamentally wrong.

    Amen brother!

  5. #5
    Registered User
    Join Date
    Feb 2003
    Posts
    595
    No, the files will not necessarily be read on the machine that wrote them. In fact, they may even be read on a different platform -- I'm already testing for endianness & coding to accomodate that -- so it's silly to knock myself out just to save a few lines of code.

  6. #6
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    4,214
    O_o

    I think I'll just ignore the question.

    Instead I offer this: you probably don't need most of that garbage for the lifetime of the image object. Serializing the object can be handled with significantly less knowledge than what you've provided. If you organize the variables in the class correctly you will circumvent some padding. And, so as you know, bitfields are subject to endianness with pragmas subject to compiler whims.

    Soma

  7. #7
    Registered User
    Join Date
    Feb 2003
    Posts
    595
    Thanks for your comments Soma.

    The thrust of my question was not about saving space. I just want to be sure my files can be transferred correctly between x86 PCs and powerPC Macs. It's handy to keep the "garbage" to facilitate writing files that can conveniently be viewed by humans (or me) to see what the image-processing accomplished.

    Regarding your bitfield comment: do I understand correctly that it applies only to fields in a structure that are explicitly declared to be bitfields and not to anything I wrote in post #1?

  8. #8
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    4,214
    It's handy to keep the "garbage" to facilitate writing files that can conveniently be viewed by humans (or me) to see what the image-processing accomplished.
    You misunderstood. (That's probably my fault. I like comments that keep people guessing.)

    I have no doubt that you eventually need all of that information. (I know you do seeing as it is the BMP file format header and DIB information header.)

    I'm saying you don't need all of that information for the life of an image object. (I assume you want to read an image file, perform an operation on the data, and write the result to an image file.) Regardless of the operations you intend to perform, most of that information is only required while reading or writing the file.

    Regarding your bitfield comment: do I understand correctly that it applies only to fields in a structure that are explicitly declared to be bitfields and not to anything I wrote in post #1?
    It doesn't apply to what you have done.

    I was simply giving you advanced warning of endianness issues with bitfields should you attempt to manually pack your structure by using them.

    Soma

  9. #9
    Registered User
    Join Date
    Feb 2003
    Posts
    595
    Got it. Thanks again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Strange struct padding?
    By cyberfish in forum C++ Programming
    Replies: 8
    Last Post: 07-12-2011, 09:42 PM
  2. Structural Padding??
    By shwetha_siddu in forum C Programming
    Replies: 13
    Last Post: 07-02-2008, 12:28 PM
  3. string padding and replacement functions
    By George2 in forum Tech Board
    Replies: 4
    Last Post: 11-19-2006, 12:40 AM
  4. Prob with padding in BMP image files
    By tin in forum Game Programming
    Replies: 2
    Last Post: 01-09-2006, 07:23 AM
  5. Structure Padding, pragma pack...
    By P.Phant in forum C Programming
    Replies: 4
    Last Post: 06-04-2003, 05:56 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21