Array assignment via struct

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Joe Wright

    #31
    Re: Array assignment via struct

    Lawrence Kirby wrote:[color=blue]
    > On Sat, 06 Aug 2005 08:02:38 -0400, Joe Wright wrote:
    >
    >[color=green]
    >>Jack Klein wrote:
    >>[color=darkred]
    >>>On Fri, 05 Aug 2005 16:24:25 -0400, Joe Wright <jwright@comcas t.net>
    >>>wrote in comp.lang.c:
    >>>
    >>>
    >>>
    >>>>Lawrence Kirby wrote:[/color][/color]
    >
    >
    > ...
    >
    >[color=green][color=darkred]
    >>>> *(S*)A = sa;
    >>>
    >>>
    >>>Here is where you invoke undefined behavior, since A isn't dynamically
    >>>allocated. There is no guarantee that A meets the alignment
    >>>requiremen ts for an S. The compiler might generate code that assumes
    >>>that A is, causing some sort of trap on some platforms, or possible
    >>>misaligned data or overwriting the destination array.
    >>>[/color]
    >>
    >>All of S is an array of char. What alignment requirements might there be
    >>for an S? None. Structures don't have alignment requirements, their
    >>members do. What are the alignment requirements of a char array?[/color]
    >
    >
    > Any object type can have alignment requirements. A structure's alignment
    > requirements must meet the requirements of all of its members, but there's
    > nothing to stop it being stricter. The reason for doing this is speed,
    > word aligned access can be faster even for smaller objects. Consider for
    > example optimised strcpy() memcpy() etc. code that operates a word at a
    > time.
    >
    >
    >[color=green][color=darkred]
    >>>I strongly dislike people who write code like this. Especially if I
    >>>have to clean up after the 'clever' programmer. It would never pass a
    >>>code inspection at any shop with decent standards. Shops that don't
    >>>do code inspections don't have decent standards by definition.
    >>>[/color]
    >>
    >>You 'strongly dislike people' who try to get 'clever' with C in a
    >>newsgroup posting? Boy, are you tough.[/color]
    >
    >
    > When the "clever" method is obscure and possibly wrong (or not easy to
    > prove correct) and there is "dumb" simple, clear and correct method
    > available I'd have to agree.
    >
    >[color=green]
    >>I thought you'd get me for not checking the malloc() returns and not
    >>free()ing ps and pa before exit. You never know your luck.[/color]
    >
    >
    > There's that too. :-)
    >
    > Lawrence[/color]

    Ok, I give up.

    Too clever I suppose. Except for this thread, I don't think I've ever
    done that: disguise an array as a struct so that it can be assigned to
    or used as a value to be assigned to a struct.

    Kieth, Stan, Netocrat and Tim notwithstanding , when Chris Torek and
    Lawrence Kirby tell me I'm all wet, I'm wet.

    It's not just C, I love this group too.

    --
    Joe Wright
    "Everything should be made as simple as possible, but not simpler."
    --- Albert Einstein ---

    Comment

    • Eric Laberge

      #32
      Re: Array assignment via struct

      Regarding my post:

      Thanks to all who replied to me, I didn't expected such a number of (highly
      interresting) answers.

      I mostly note that padding and alignment could cause the implementation to
      be not portable, so I'll do it differently.

      Why I wanted to do this this way was because I had to implement some kind of
      side effect to assignments, and, like C, assignments are nothing more than
      binary operators that return a value, so a=b=c+d is effectively
      a=(b=(c+d)). Seeing the gold mine of knowledge here, I know you all know
      that. Now I know, that's why functions like memcpy returns the destination
      pointer, so that this can be done too, but I had to also call another
      function concurrently, and I looked for an easy way to achieve what I had
      in mind.

      My final solution, and I feel somewhat ashamed for having thought of this so
      late, is simply to wrap up the memcpy and the side-effect functions in an
      inline function, so code-generation will still be easilly done and *much*
      more cleaner. Clean code, no matter if it's human or computer generated, is
      essential for me too. "Better safe than sorry".

      Thanks again,
      --
      Eric Laberge

      Comment

      • Chris Croughton

        #33
        Re: Array assignment via struct

        On Mon, 08 Aug 2005 19:56:13 GMT, Keith Thompson
        <kst-u@mib.org> wrote:
        [color=blue]
        > Chris Croughton <chris@keristor .net> writes:[color=green]
        >> On Sun, 07 Aug 2005 00:24:58 +1000, Netocrat
        >> <netocrat@membe rsat.dodo.com.a u> wrote:[/color]
        > [snip][color=green][color=darkred]
        >>> Yeah, that's why I called it a pedantic point later in the post. Probably
        >>> the DS9000 is the only implementation to include padding. Anyhow you lose
        >>> nothing by using sizeof(S) instead of LEN and you are assured of
        >>> compliance.[/color]
        >>
        >> No, it isn't a pedantic point, there are many systems where a struct is
        >> rounded up in length to the "worst case~ alignment size. In the case
        >> given, it probably won't happen all that often because LEN is 20 which
        >> is a multiple of 4 (although certain 64 bit machines may need alignment
        >> to 8 byte boundaries). If LEN were an odd number a lot of systems would
        >> round the size up to at least the nearest even number.[/color]
        >
        > For example, given:
        >
        > struct foo {
        > char s[3];
        > };
        >
        > it would make sense on many platforms to pad struct foo to 4 bytes and
        > require 4-byte alignment. That way, assigning a struct foo or passing
        > it as an argument could be done with a single 4-byte instruction, just
        > as for a 32-bit (assuming CHAR_BIT==8) integer.[/color]

        Yes, efficiency of generated code is one of the reasons for doing it.
        On the other hand, even a compiler which generates memcpy() (or its
        assembler equivalent) for all copies might still round it up because it
        rounds up all structures "just in case" (the standard doesn't say that
        it can't). And of course on a word based machine it may only be able to
        allocate chunks in multiple bytes anyway.
        [color=blue]
        > On the other hand, an implementer might decide that copying structures
        > is rare enough that the extra padding isn't worthwhile. <OT>gcc
        > doesn't add extra padding, at least by default, at least on the one
        > platform where I tried this.</OT>[/color]

        <OT>
        This may be a feature of gcc, it does it both on x86 (Debian Linux) and
        on a MicroVAX 3100/M40 running OpenBSD (unfortunately my uVAX 3100/90
        running OpenVMS with the Digital C compliler isn't working at the
        moment, and I don't have any Sun Sparcs or Digital Alpha machines online
        at present). Ye gods, the uVAX is slow (5 minutes to test 32MB RAM
        gives an idea)...
        </OT>
        [color=blue]
        > [snip]
        >[color=green]
        >> Or a non-optimising one. A fully optimising compiler might notice that
        >> the only thing in the structure is a char array, and hence generate a
        >> structure of length LEN, where a non-optimising one would "play it safe"
        >> by making sure that it is rounded up to a safe alignment.[/color]
        >
        > But note that the non-optimizing and fully optimizing compilers in
        > practice probably can't be the same compiler in different modes.
        > Given the way most compilers are invoked, you usually want to have the
        > same data layout in all modes, since a program can be built from
        > translation units that were compiled in different modes. (Or the
        > linker can forbid linking units compiled in different modes, but that
        > makes things more complicated.)[/color]

        Yes, good point, although I've known compilers which generated
        incompatible code when optimising for space vs. speed (sometimes putting
        parameters in registers in one mode and not the other, for instance).
        I've known gcc to have problems with optimised code interfacing to
        non-optimised code, although that may have been a bug (but not forbidden
        by the standard)...

        Chris C

        Comment

        • pete

          #34
          Re: Array assignment via struct

          Eric Laberge wrote:[color=blue]
          >
          > Regarding my post:
          >
          > Thanks to all who replied to me,
          > I didn't expected such a number of (highly
          > interresting) answers.
          >
          > I mostly note that padding and alignment could
          > cause the implementation to
          > be not portable, so I'll do it differently.[/color]

          I don't get it. The code I posted here:



          is portable code.

          --
          pete

          Comment

          • Chris Croughton

            #35
            Re: Array assignment via struct

            On Mon, 08 Aug 2005 16:18:11 -0400, Joe Wright
            <jwright@comcas t.net> wrote:
            [color=blue]
            > Kieth, Stan, Netocrat and Tim notwithstanding , when Chris Torek and
            > Lawrence Kirby tell me I'm all wet, I'm wet.[/color]

            When Chris Torek writes something, I read it, because not only is he
            almost always[0] right but he also explains it so that I know /why/ he
            is right and without being patronising or putting my back up. A lot of
            people here (and I include myself) aren't that good at saying "You're
            wrong" without offending people...

            [0] Actually, always as far as I remember except for the Fortran program
            where he got the label on the wrong line <g>...
            [color=blue]
            > It's not just C, I love this group too.[/color]

            Well, I'm still here. Although I have killfiled a lot of the obvious
            trolls (a couple of generic rules on gmail and yahoo addresses, with
            certain exceptions[1], does wonders for the signal to noise ratio)...

            [1] Since I use a scorefile rather than a killfile, I score at -999
            which means that (a) if they respond to my posts they get 'unkilled' for
            that response and (b) they are still visible so I can check if anyone
            has been caught who shouldn't have been caught and can put them in the
            exceptions list.

            Chris C

            Comment

            • Lawrence Kirby

              #36
              Re: Array assignment via struct

              On Mon, 08 Aug 2005 22:44:51 +0000, pete wrote:
              [color=blue]
              > Eric Laberge wrote:[color=green]
              >>
              >> Regarding my post:
              >>
              >> Thanks to all who replied to me,
              >> I didn't expected such a number of (highly
              >> interresting) answers.
              >>
              >> I mostly note that padding and alignment could
              >> cause the implementation to
              >> be not portable, so I'll do it differently.[/color]
              >
              > I don't get it. The code I posted here:
              >
              > http://groups-beta.google.com/group/...17f3f78?hl=en&
              >
              > is portable code.[/color]

              If you want to use a structure containing an array instead of an array in
              your code that's fine. There may be problems if:

              1. there is code that already creates arrays that are not structure
              wrapped, and more seriously:

              2. the size of the array is not known at compile time.

              Lawrence

              Comment

              • Dave Thompson

                #37
                Re: Array assignment via struct

                On Sat, 06 Aug 2005 17:19:44 +1000, Netocrat
                <netocrat@membe rsat.dodo.com.a u> wrote:
                [color=blue]
                > On Fri, 05 Aug 2005 21:52:07 -0700, Krishanu Debnath wrote:
                >[color=green]
                > >
                > > Jack Klein wrote:[/color][/color]
                <snip ... auto char A[N] accessed as struct containing char[N]>[color=blue][color=green][color=darkred]
                > >> Here is where you invoke undefined behavior, since A isn't dynamically
                > >> allocated. There is no guarantee that A meets the alignment
                > >> requirements for an S. The compiler might generate code that assumes[/color][/color]
                >
                > Given that element a must be located at the start of struct S, and that it
                > is a char array of size LEN, it's hard to see how it could be aligned
                > differently to the char array A of size LEN. Are you referring to this
                > specific case or in general? If this case, could you explain how the
                > standard allows the alignments to be different?
                >[/color]
                Except that certain pairs like qualified and unqualified pointers to
                the same type must be the same, the standard allows the alignment of
                anything except char to be anything the implementation wants, though
                it nonnormatively expects transitivity, footnote 57 to 6.3.2.3p7.

                "Classic" Tandem^WCompaq^ WHP NonStop, still supported in emulation, is
                (was) 16-bit-word (=2 x 8-bit byte) oriented, and requires basic types
                above char (>= short) to be word aligned, and _all_ struct (and union)
                even if they contain only char(s). Hence a char [N] might sometimes
                not be word-aligned while a struct { char x [N] } must. Although, on
                that implementation a "top-level" array variable is always allocated
                word-aligned, so the case _given here_ was OK.

                - David.Thompson1 at worldnet.att.ne t

                Comment

                Working...