Alignment of struct members

Discussion in 'C Programming' started by bluejack, May 28, 2007.

  1. bluejack

    bluejack Guest

    Hit a super weird bug, which baffled me for some time. Here's the
    setup:

    struct thing {
    unsigned char byte1;
    unsigned char byte2;
    unsigned char byte3;
    unsigned long long big_number;
    char* string_ptr;
    };

    void set_default_values(struct thing* t)
    {
    t->byte1 = 0;
    t->byte2 = 1;
    t->byte3 = 2;
    t->big_number = 0;
    t->string_ptr = strdup("This is a string.");
    }

    Ok? What am I doing wrong?

    After calling set_default values, my struct is:

    byte1 = 0, byte2 = 1, byte3 = 2, big_number =
    157823974298375928572234, string_ptr = "his is a string."

    The big_number there is not exact. I can try to work up a functioning
    microprogram if this is at all worth pursuing.

    Eventually, after the byte3 member, I added an 'unsigned char unusued'
    member, and my problems went away. My understanding was that the
    compiler was supposed to align bytes and optionally pad if required by
    the os. Is my understanding wrong? I'm using an ordinary gdb on an
    ordinary linux. This *can't* be a broken compiler problem, can it? (I
    realize it's almost certainly a broken programmer problem; and I
    thought I'd call for smacks on the head before pursuing any further.)

    -Bluejack
    bluejack, May 28, 2007
    #1
    1. Advertising

  2. bluejack <> writes:
    > Hit a super weird bug, which baffled me for some time. Here's the
    > setup:
    >
    > struct thing {
    > unsigned char byte1;
    > unsigned char byte2;
    > unsigned char byte3;
    > unsigned long long big_number;
    > char* string_ptr;
    > };
    >
    > void set_default_values(struct thing* t)
    > {
    > t->byte1 = 0;
    > t->byte2 = 1;
    > t->byte3 = 2;
    > t->big_number = 0;
    > t->string_ptr = strdup("This is a string.");
    > }
    >
    > Ok? What am I doing wrong?
    >
    > After calling set_default values, my struct is:
    >
    > byte1 = 0, byte2 = 1, byte3 = 2, big_number =
    > 157823974298375928572234, string_ptr = "his is a string."
    >
    > The big_number there is not exact. I can try to work up a functioning
    > microprogram if this is at all worth pursuing.
    >
    > Eventually, after the byte3 member, I added an 'unsigned char unusued'
    > member, and my problems went away. My understanding was that the
    > compiler was supposed to align bytes and optionally pad if required by
    > the os. Is my understanding wrong? I'm using an ordinary gdb on an
    > ordinary linux. This *can't* be a broken compiler problem, can it? (I
    > realize it's almost certainly a broken programmer problem; and I
    > thought I'd call for smacks on the head before pursuing any further.)


    It's impossible to be sure without seeing a working complete program.

    You mention gdb (a debugger). Is that what you're using to display
    the value of the struct? If so, that makes it hard to tell whether
    it's a compiler bug or a debugger bug.

    See if you can reproduce the problem with a small program that prints
    the values itself rather than depending on the debugger.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, May 28, 2007
    #2
    1. Advertising

  3. bluejack

    bluejack Guest

    On May 28, 1:30 am, Keith Thompson <> wrote:

    > You mention gdb (a debugger). Is that what you're using to display
    > the value of the struct? If so, that makes it hard to tell whether
    > it's a compiler bug or a debugger bug.
    >
    > See if you can reproduce the problem with a small program that prints
    > the values itself rather than depending on the debugger.


    Yeah, that cleared it up for me. It was a display problem with the
    debugger. :/

    I encounter problems with my tools so rarely I guess I trust them a
    little too much.

    There is source for a more recent version of the debugger available;
    and I expect that bug will have been corrected. Thanks again.

    -Bluejack
    bluejack, May 28, 2007
    #3
  4. bluejack

    Tor Rustad Guest

    bluejack wrote:
    > Hit a super weird bug, which baffled me for some time. Here's the
    > setup:
    >
    > struct thing {
    > unsigned char byte1;
    > unsigned char byte2;
    > unsigned char byte3;
    > unsigned long long big_number;
    > char* string_ptr;
    > };
    >
    > void set_default_values(struct thing* t)
    > {
    > t->byte1 = 0;
    > t->byte2 = 1;
    > t->byte3 = 2;
    > t->big_number = 0;
    > t->string_ptr = strdup("This is a string.");
    > }
    >
    > Ok? What am I doing wrong?


    strdup()is non-standard.

    How do you print the 'big-number'? Remember, this member has 'long long'
    type, which is not supported in C89.

    --
    Tor <torust [at] online [dot] no>
    Tor Rustad, May 28, 2007
    #4
  5. bluejack

    bluejack Guest

    On May 28, 4:23 am, CBFalconer <> wrote:

    > You didn't show a complete compilable program, in particular you
    > omitted the call to set_default_values, the declaration and
    > initialization of t, etc.


    I know, I was looking for conceptual guidance; which Keith provided.

    > My guess is that you never allocated data space for t.


    Looked like a memory smash to me, too, and I actually spent some time
    looking at that; but it turned out to be a display issue in an older
    (but "current" according to yum) version of gdb.

    The actual bug that surfaced in execution turned out to be
    elsewhere... I was pursuing a red herring because it *looked* so
    wrong.

    Lesson learned: don't always trust your tools; but be careful about
    which tool you blame. (I had been thinking it might be a compiler bug,
    although I was skeptical, because in my experience it's *never* a
    compiler bug; which was why I posted here...)

    -b
    bluejack, May 28, 2007
    #5
  6. bluejack <> writes:
    > On May 28, 4:23 am, CBFalconer <> wrote:
    >> You didn't show a complete compilable program, in particular you
    >> omitted the call to set_default_values, the declaration and
    >> initialization of t, etc.

    >
    > I know, I was looking for conceptual guidance; which Keith provided.
    >
    >> My guess is that you never allocated data space for t.

    >
    > Looked like a memory smash to me, too, and I actually spent some time
    > looking at that; but it turned out to be a display issue in an older
    > (but "current" according to yum) version of gdb.
    >
    > The actual bug that surfaced in execution turned out to be
    > elsewhere... I was pursuing a red herring because it *looked* so
    > wrong.
    >
    > Lesson learned: don't always trust your tools; but be careful about
    > which tool you blame. (I had been thinking it might be a compiler bug,
    > although I was skeptical, because in my experience it's *never* a
    > compiler bug; which was why I posted here...)


    Another lesson: try narrowing your program down to a small
    self-contained program that exhibits the problem. In your case, you
    could have wrapped the declarations you posted with another dozen or
    so lines of code, creating a small program that calls your
    initialization routine and prints the values of the members of the
    structure using printf. This is especially useful if your debugger
    isn't being as helpful as it should. If the problem is in your code,
    you're likely to figure it out while narrowing it down. If you still
    don't know where the problem is, you can post the code here; if it's
    portable C, we can probably let you know whether the code is behaving
    as it should according to the standard.

    <OT>Since it apparently turned out to have been a gdb bug, do a Google
    search, or check the change log in the latest gdb release, to find out
    whether it's been fixed, and in what release.</OT>

    There's another possibility that I should have mentioned. You're
    using long long, which is a new feature of C99. C99 conformance is
    incomplete in most implementations. Since the compiler and the
    runtime library are often provided separately, it's entirely possible
    for the compiler to support long long, but for printf not to support
    the "%lld" format. In this case, you can convert the value to long if
    it happens to be in range, or roll your own conversion routine. (That
    didn't turn out to be the problem in your case, but others might find
    this helpful.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, May 28, 2007
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. JFCM
    Replies:
    4
    Views:
    5,724
  2. CoolPint
    Replies:
    8
    Views:
    957
    Jeff Schwab
    Dec 14, 2003
  3. Dave
    Replies:
    3
    Views:
    360
    tom_usenet
    Aug 10, 2004
  4. Chris Fogelklou
    Replies:
    36
    Views:
    1,356
    Chris Fogelklou
    Apr 20, 2004
  5. John Reye
    Replies:
    28
    Views:
    1,342
    Tim Rentsch
    May 8, 2012
Loading...

Share This Page