Re: Question about Declare and Type

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance

From: Jim Mack (jmack_at_mdxi.nospam.com)
Date: 12/24/04


Date: Fri, 24 Dec 2004 15:57:01 -0500

Jim Carlock wrote:
> Maybe I'm confused now.
>
> I was thinking that a structure defined inside of C with pack(4)
> means that if the structure ends up with 3 bytes, an extra byte
> would be padded onto the END of the STRUCTURE. I
> don't think it gets the padding inside each unit of the structure,
> because that would break the structure, wouldn't it?
>
> I mean if you want three different bytes inside of a structure,
> you'd want:
>
> Private Type tagTest
> Byte1 As Byte
> Byte2 As Byte
> Byte3 As Byte
> End Type
>
> and in C:
>
> #pragma pack(4)
> typedef struct NetThreeByteMask {
> UCHAR byte1;
> UCHAR byte2;
> UCHAR byte3;
> }
>
> I always thought the extra byte was added at the end of the
> structure, rather than three bytes added to each variable in
> the structure.
>
> Which is correct?

Really, neither, but this isn't a good example.

In this particular case, no padding is needed within the struct, except
that if you declare an array of such, each element of the array will
have a byte of padding between it and the next element, because the
array itself must align elements on 4-byte boundaries, per OLE rules.

Padding is applied within a struct, _before_ an element, when that
element would not otherwise align to its natural size, up to the size
given in the pack() pragma. That's why placing larger elements before
smaller ones will give the optimum packing for the struct. Since the
natural size of a char or byte is 1, no padding is ever needed before a
byte within a struct. This is called "natural 4-byte alignment" (8-byte
by C default).

The OP is confused because he seems to think that #pragma pack(4) means
that each element will occupy a minimum of 4 bytes, which is
demonstrably not the case. What it really means is that every element
of 4 bytes or larger will start at an address that is a multiple of 4;
every element of 2 bytes or larger will start at an even address, and a
1-byte element may start at any address. Pack(8) simply extends that co
ncept upward by one notch.

There is a special case of this for VB "String * N" structure elements,
because they're normally composed of 2-byte (Unicode) characters in
memory, but one-byte characters when passed to a Declared function --
they're converted to MBCS (ANSI) characters. So the alignment within a
struct can vary from its definition, when passed to a C function.
That's why the best advice is to replace all "String * N" elements with
static byte arrays.

-- 
    Jim Mack
    MicroDexterity Inc
    www.microdexterity.com


Relevant Pages

  • Re: Size of char on a 64 bit machine
    ... > Essentially, usually, but not necessarily: Characters in an array are ... > usually stored sequentially without any padding in between. ... but not between elements of an array. ... Given an array object arr, the number of elements can be computed by ...
    (comp.lang.c)
  • Re: Does an array of char have alignment issues?
    ... I have no idea what you mean by "tile an array". ... padding bytes after the first char, ... after the last member, ... A union can also ...
    (comp.sys.arm)
  • Re: Malloc Query
    ... the arena is an array even though the program using it does not care. ... so you have to account for that when using a pointer ... the alignment requirement, to allow for arrays... ... Adding one byte of padding would do the trick. ...
    (comp.lang.c)
  • Re: A twist on OTP for an outstandingly secure channel?
    ... Imagine an OTP. ... bits would be (assuming 8 bit characters. ... sequential plaintext data). ... Your scheme has a far higher ratio of padding than ...
    (sci.crypt)
  • Re: Malloc Query
    ... the arena is an array even though the program using it does not care. ... Suppose an 'int' has a size and alignment of 4 bytes. ... Adding one byte of padding would do the trick. ...
    (comp.lang.c)