struct and union alignment

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Dan Pop

    #16
    Re: struct and union alignment

    In <2rh5sgF1a5m6aU 1@uni-berlin.de> "S.Tobias" <sNOiSPAMt@amu. edu.pl> writes:
    [color=blue]
    >Keith Thompson <kst-u@mib.org> wrote:[color=green]
    >> "S.Tobias" <sNOiSPAMt@amu. edu.pl> writes:[color=darkred]
    >> > 6.2.5#26 (Types):
    >> > All pointers to structure types shall have the same representation and
    >> > alignment requirements as each other. All pointers to union types shall
    >> > have the same representation and alignment requirements as each other.
    >> >
    >> > Does it mean that *all* structure (or union) types have the same
    >> > alignment?[/color][/color]
    >[color=green]
    >> No, it's referring to the alignment of the pointer, not the alignment
    >> of the struct or union.[/color]
    >
    >What's the difference?[/color]

    If you can't grasp the difference between a pointer and the pointed-to
    object, stop messing with the C standard and read K&R2 (again).

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email: Dan.Pop@ifh.de
    Currently looking for a job in the European Union

    Comment

    • xarax

      #17
      Re: struct and union alignment

      "Mabden" <mabden@sbc_glo bal.net> wrote in message
      news:mBK4d.697$ JG2.315@newssvr 14.news.prodigy .com...[color=blue]
      > "Flash Gordon" <spam@flash-gordon.me.uk> wrote in message
      > news:pstb22x2mb .ln2@brenda.fla sh-gordon.me.uk...[color=green]
      > > On 23 Sep 2004 19:10:38 GMT
      > > "S.Tobias" <sNOiSPAMt@amu. edu.pl> wrote:
      > >[color=darkred]
      > > > Does it mean that *all* structure (or union) types have the same
      > > > alignment?
      > > > Eg. type
      > > > struct { char c; }
      > > > and
      > > > struct { long double ldt[11]; }
      > > > have the same alignment requirements?[/color][/color]
      >
      > Unions also have the caveat that they be aligned according to the most
      > restrictive item in the union. So a struct {char a; double z;} could
      > have a different alignment than union {char a; double z;}.[/color]

      Wrong. Both the struct and union have the same
      alignment as double. A struct's alignment is
      the same as the strictest (widest) alignment
      of any of its members, including nested aggregates.
      Same rules apply for union. The alignment is that
      of the strictest alignment of any of its members,
      including nested aggregates (other unions or
      structs).

      Maybe you are confusing the size with alignment?


      Comment

      • Dan Pop

        #18
        Re: [OT] struct and union alignment

        In <2riittF19ulrhU 2@uni-berlin.de> "S.Tobias" <sNOiSPAMt@amu. edu.pl> writes:
        [color=blue]
        >Christian Kandeler <christian.kand eler@hob.de_inv alid> wrote:[color=green]
        >> S.Tobias wrote:[/color]
        >[color=green][color=darkred]
        >> > I'm sorry, but I can't see how can you define a pointer to anonymous
        >> > struct in the first place (since that struct has no name).[/color][/color]
        >[color=green]
        >> struct {
        >> int a;
        >> int b;
        >> } *pointer_to_ano nymous_struct;[/color]
        >
        >OIC, didn't think of that.
        >
        >But then again, what would be a use for that? Since
        >this is not a struct object definition, there are no objects
        >of type pointer_to_anon ymous_struct points to.
        >
        >Mmmm, could it be:
        > pointer_to_anon ymous_struct = malloc(sizeof *pointer_to_ano nymous_struct);
        >?
        >But what is the point in having an anonymous struct then?[/color]

        Look at it the other way round: in your own example, what would be the
        point of using a tag in the structure definition?
        [color=blue]
        >Could you supply a real-life example?[/color]

        Sure:

        struct { ... } foo, bar, baz;

        foo, bar and baz are all the objects of this type needed by the program
        and they are used in a single translation unit. What would a tag buy you?

        Dan
        --
        Dan Pop
        DESY Zeuthen, RZ group
        Email: Dan.Pop@ifh.de
        Currently looking for a job in the European Union

        Comment

        • S.Tobias

          #19
          Re: [OT] struct and union alignment

          Dan Pop <Dan.Pop@cern.c h> wrote:[color=blue]
          > In <2rh5sgF1a5m6aU 1@uni-berlin.de> "S.Tobias" <sNOiSPAMt@amu. edu.pl> writes:[color=green]
          > >Keith Thompson <kst-u@mib.org> wrote:[/color][/color]
          [color=blue][color=green][color=darkred]
          > >> No, it's referring to the alignment of the pointer, not the alignment
          > >> of the struct or union.[/color]
          > >
          > >What's the difference?[/color][/color]
          [color=blue]
          > If you can't grasp the difference between a pointer and the pointed-to
          > object, stop messing with the C standard and read K&R2 (again).[/color]

          Why being so aggressive at me? My seemingly naive question was not
          asked without a reason, which I explained at length in my answer
          to Barry Schwarz' post (I assume that hadn't reached you before
          you sent yours). I think my remark in parentheses (which you didn't
          quote) more than suggests I do understand the difference between
          pointer type and pointed to type (I explicitly wrote that I did consider
          pointer type alignment possibility, but rejected it).

          I don't understand how you can judge other people's understanding
          only after one posting. Please, explain yourself.

          --
          Stan Tobias
          sed 's/[A-Z]//g' to email

          Comment

          • Chris Torek

            #20
            Re: struct and union alignment

            In article <news:2rii78F19 ulrhU1@uni-berlin.de>
            S.Tobias <sNOiSPAMt@amu. edu.pl> wrote:
            [much snippage][color=blue]
            >The last manner is also found in: 6.3.2.3#7 (Pointers) and 7.20.3#1
            >(Memory management functions). See for yourself: in both cases "pointer
            >alignment" refers to the pointer *value*, not pointer type.[/color]

            I am not going to address most of this (due to lack of time), but
            I want to make several points here.

            First, the value of a pointer to some type "T" -- i.e., a value of
            type "T *" -- indeed possesses this "alignment" characteristic, so
            that it is possible to ask whether such a pointer is correctly
            aligned. (This question is inherently machine-dependent, however,
            and on *some* machines it is meaningless.)

            But note that if we store this pointer value in an object:

            T *pointer_object ;

            we then have an *object*, not a variable. This object can have an
            address:

            T **p2 = &pointer_object ;

            (here the object's address is stored in yet another object, "p2",
            of type "T **). If "pointer_object " has an address, that value --
            a value of type "T **" -- *also* possesses this "alignment"
            characteristic. Thus, we can ask not only whether the value stored
            in "pointer_object " is correctly aligned, but also whether
            "pointer_object " itself is correctly aligned. Having stored
            &pointer_obj ect in p2, we can then ask whether "the object p2" is
            correctly aligned, via this question:

            "does &p2 satisfy its machine-dependent alignment constraints?"

            and if we store &p2 in yet another object:

            T ***p3 = &p2;

            we can then go on to ask whether "the object p3" (or more precisely,
            the value produced by &p3) is correctly aligned, and so on.

            There are thus four possible machine-dependent alignment constraints
            arising so far:

            (1) the value stored in pointer_object (of type "T *")
            (2) the value produced by &pointer_obj ect (type "T **")
            (3) the value produced by &p2 (type "T ***")
            (3) the value produced by &p3 (type "T ****")

            and it makes some sense to ask whether all of them are satisified,
            and to ask whether any or all four of these machine-dependent
            alignment constraints are identical. Some of the answers are of
            course machine-dependent. Since the objects named "pointer_object ",
            "p2", and "p3" are allocated by the compiler, they had better be
            correctly aligned -- the C programmer is not the one responsible
            for this -- but the rest of the answers require looking at the
            machine.

            For a number of existing, even common, machines today, the alignment
            constraints for "T *" and "T **" often differ, depending on T.
            For instance, "char *" always, by definition, needs only 1-byte
            alignment ("C byte", not necessarily 8-bit-octet, although the
            machines I am thinking of happen to have 8-bit C bytes too); but
            "char **" often requires 4 or 8 byte alignment (32-bit or 64-bit
            SPARC and MIPS, for instance).

            Now, given the original example, or something at least close to
            it:

            struct C { char c; };
            struct D { double d; };

            you will find that, e.g., SPARC systems have sizeof(struct C) == 1
            and align "struct C" objects on byte boundaries, while sizeof(struct D)
            == 8 and "struct D" objects are always found on 8-byte boundaries.
            Nonetheless, on those machines in 32-bit mode (or always for V8 and
            earlier SPARC systems), "struct C *" and "struct D *" objects
            are always aligned on 4-byte boundaries. In other words, given:

            struct C *p1, **p2;
            ... set p1 and p2 ...

            we can test the "alignment validity" (on that SPARC machine, in a
            machine-dependent manner) with:

            int is_p1_aligned(v oid) {
            /* p1 is always properly aligned */
            return 1;
            }

            int is_p2_aligned(v oid) {
            /* p2 is properly aligned if and only if its low 2 bits are 0 */
            return ((int)p2 & 3) == 0;
            }

            If we add "struct D *p3", however, the "is_p3_alig ned" test becomes:

            int is_p3_aligned(v oid) {
            /* p3 is properly aligned if and only if its low 3 bits are 0 */
            return ((int)p3 & 7) == 0;
            }

            Thus, the "aligned-ness" of a pointer depends on its type as well as
            its value; and for two "struct T1 *" and "struct T2 *" values, the
            "aligned-ness" of those two value may require different tests.
            --
            In-Real-Life: Chris Torek, Wind River Systems
            Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
            email: forget about it http://web.torek.net/torek/index.html
            Reading email is like searching for food in the garbage, thanks to spammers.

            Comment

            • Keith Thompson

              #21
              Re: struct and union alignment

              "S.Tobias" <sNOiSPAMt@amu. edu.pl> writes:[color=blue]
              > Keith Thompson <kst-u@mib.org> wrote:[color=green]
              >> For example, a pointer object might require 4-byte alignment, whereas
              >> a char object requires only 1-byte alignment. When the standard says
              >> void* and char* have to have the same alignment requirements, the
              >> intent is that they're interchangeable as arguments to functions.[/color]
              >
              > Right.
              > extern char *pc;
              > void free(void *p);
              > free(pc); //correct
              >
              > (Note: we don't need same representation requirement in the above
              > example. This requirement is necessary eg. for variadic arguments:
              > printf("%p", pc);
              > - no cast to void* required.)
              >[color=green]
              >> Requiring 1-byte alignment for char* but only 4-byte alignment for
              >> void* could break this.[/color]
              >
              > No. I see no reason to require same alignment for types void* and char*,
              > because in function arguments they're passed by *value* (think conversion).
              > Similarly, long and char do not have to have same alignment, but we may
              > always use them in arguments "interchangeabl y":
              > extern long l;
              > extern char c;
              > int f_char(unsigned char c);
              > int f_long(unsigned long l);
              > f_char(l); //both calls correct
              > f_long(c);[/color]

              No, we can't use long and char in arguments interchangeably . If
              there's a prototype, the value is converted to the expected type;
              you're not passing a char to f_long, you're passing a long. If
              there's no visible prototype, the call f_long(c) invokes undefined
              behavior.

              Examples involving implicit conversions aren't relevant to the point.
              In the call free(pc) above, you're not passing a char* to free(),
              you're passing a void* value, the result of the implicit conversion of
              the value of pc.

              The interchangeabil ity referred to in the footnote in C99 6.2.5
              involves cases where something of one type is interpreted as another,
              without a conversion (either explicit or implicit), such as a function
              call with no prototype in scope, a call to a variadic function, or a
              reference to a union member.

              Suppose void* required 4-byte (word) alignment, but char* only
              required 1-byte alignment (I'm referring to the required alignment for
              a pointer object). Suppose the compiler has to generate different
              code to access a byte-aligned char* than a word-aligned void*. Now
              consider your call printf("%p", pc), where pc is a char*. The calling
              code pushes the value of pc onto the stack at an odd address (assume
              that there is a stack). The code inside printf that accesses the
              argument expects a void*, so it uses an instruction that only works on
              word-aligned values. Kaboom.

              That's how differing alignments for void* and char* can cause problems
              in parameter passing.

              [snip]

              (I'm not responding to the rest of your message, at least for now,
              mostly because I don't have time to do it justice.)

              --
              Keith Thompson (The_Other_Keit h) kst-u@mib.org <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.

              Comment

              • Keith Thompson

                #22
                Re: struct and union alignment

                Christian Kandeler <christian.kand eler@hob.de_inv alid> writes:[color=blue]
                > S.Tobias wrote:
                >[color=green]
                >> I'm sorry, but I can't see how can you define a pointer to anonymous
                >> struct in the first place (since that struct has no name).[/color]
                >
                > struct {
                > int a;
                > int b;
                > } *pointer_to_ano nymous_struct;[/color]

                I suspect (but I'm only guessing) that the reference to "anonymous
                structs" was actually meant to refer to incomplete types, such as

                #include <stdio.h>
                int main(void)
                {
                struct incomplete *ptr;
                printf("sizeof ptr = %d\n", (int)sizeof ptr);
                return 0;
                }

                The compiler has to determine the representation of ptr without
                knowing anything about "struct incomplete" except that it's a struct.

                --
                Keith Thompson (The_Other_Keit h) kst-u@mib.org <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.

                Comment

                • Keith Thompson

                  #23
                  Re: struct and union alignment

                  Chris Torek <nospam@torek.n et> writes:[color=blue]
                  > In article <news:2rii78F19 ulrhU1@uni-berlin.de>
                  > S.Tobias <sNOiSPAMt@amu. edu.pl> wrote:
                  > [much snippage][color=green]
                  >>The last manner is also found in: 6.3.2.3#7 (Pointers) and 7.20.3#1
                  >>(Memory management functions). See for yourself: in both cases "pointer
                  >>alignment" refers to the pointer *value*, not pointer type.[/color]
                  >
                  > I am not going to address most of this (due to lack of time), but
                  > I want to make several points here.
                  >
                  > First, the value of a pointer to some type "T" -- i.e., a value of
                  > type "T *" -- indeed possesses this "alignment" characteristic, so
                  > that it is possible to ask whether such a pointer is correctly
                  > aligned. (This question is inherently machine-dependent, however,
                  > and on *some* machines it is meaningless.)
                  >
                  > But note that if we store this pointer value in an object:
                  >
                  > T *pointer_object ;
                  >
                  > we then have an *object*, not a variable. This object can have an
                  > address:
                  >
                  > T **p2 = &pointer_object ;[/color]
                  [...]

                  Chris, did you mean to write that we have an object, not a *value*?
                  (T is both an object and a variable.)

                  --
                  Keith Thompson (The_Other_Keit h) kst-u@mib.org <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.

                  Comment

                  • CBFalconer

                    #24
                    Re: struct and union alignment

                    "S.Tobias" wrote:[color=blue]
                    >[/color]
                    .... snip ...[color=blue]
                    >
                    > (Note: we don't need same representation requirement in the above
                    > example. This requirement is necessary eg. for variadic arguments:
                    > printf("%p", pc);
                    > - no cast to void* required.)[/color]

                    On the contrary, that statement specifically requires a cast to
                    void*, unless pc is already of type void*.

                    --
                    "It is not a question of staying the course, but of changing
                    the course" - John Kerry, 2004-09-20
                    "Ask any boat owner the eventual result of continuing the
                    present course indefinitely" - C.B. Falconer, 2004-09-20


                    Comment

                    • Keith Thompson

                      #25
                      Re: struct and union alignment

                      CBFalconer <cbfalconer@yah oo.com> writes:[color=blue]
                      > "S.Tobias" wrote:[color=green]
                      >>[/color]
                      > ... snip ...[color=green]
                      >>
                      >> (Note: we don't need same representation requirement in the above
                      >> example. This requirement is necessary eg. for variadic arguments:
                      >> printf("%p", pc);
                      >> - no cast to void* required.)[/color]
                      >
                      > On the contrary, that statement specifically requires a cast to
                      > void*, unless pc is already of type void*.[/color]

                      That's questionable, IMHO.

                      As a matter of style, I would always cast the argument to void* rather
                      than depend on an ambiguous guarantee of compatibility. But C99
                      6.2.5p26 says:

                      A pointer to void shall have the same representation and alignment
                      requirements as a pointer to a character type.

                      and a footnote says:

                      The same representation and alignment requirements are meant to
                      imply interchangeabil ity as arguments to functions, return values
                      from functions, and members of unions.

                      I'm not convinced that requiring the same representation and alignment
                      requirements is really enough to guarantee that printf("%p", pc); will
                      actually work (where pc is a char*), but that does seem to be the
                      intent -- and I'd be surprised if there were an actual C90 or C99
                      implementation on which it doesn't work. (Making it break would
                      require some perversity on the part of the implementer.)

                      On the other hand, there are no guarantees regarding
                      printf("%p", pi);
                      where pi is of type int*; void* and int* could have different
                      representations .

                      (I assume that pc and pi have valid values.)

                      --
                      Keith Thompson (The_Other_Keit h) kst-u@mib.org <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.

                      Comment

                      • Flash Gordon

                        #26
                        Re: struct and union alignment

                        On Fri, 24 Sep 2004 18:51:13 GMT
                        Keith Thompson <kst-u@mib.org> wrote:
                        [color=blue]
                        > Christian Kandeler <christian.kand eler@hob.de_inv alid> writes:[color=green]
                        > > S.Tobias wrote:
                        > >[color=darkred]
                        > >> I'm sorry, but I can't see how can you define a pointer to[/color]
                        > >anonymous> struct in the first place (since that struct has no name).
                        > >
                        > >
                        > > struct {
                        > > int a;
                        > > int b;
                        > > } *pointer_to_ano nymous_struct;[/color]
                        >
                        > I suspect (but I'm only guessing) that the reference to "anonymous
                        > structs" was actually meant to refer to incomplete types, such as[/color]

                        Yes. I was having a bad day.
                        [color=blue]
                        > The compiler has to determine the representation of ptr without
                        > knowing anything about "struct incomplete" except that it's a struct.[/color]

                        Indeed.
                        --
                        Flash Gordon
                        Sometimes I think shooting would be far too good for some people.
                        Although my email address says spam, it is real and I read it.

                        Comment

                        • S.Tobias

                          #27
                          Re: struct and union alignment

                          Keith Thompson <kst-u@mib.org> wrote:
                          [color=blue]
                          > Examples involving implicit conversions aren't relevant to the point.[/color]

                          True, I missed it. Now that you later mention it, I guess (I'm not
                          a historian) that long ago when there was no void type, the function
                          declarations didn't have prototypes either, so the declarations for
                          free and memcpy were:
                          free();
                          free(p) char *p; {...}
                          char *memcpy();
                          char *memcpy(d, s, n) char *d, *s; size_t n; {...}
                          And this is probably the interchangeabil ity in arguments that the
                          Rationale refers to, ie. that we may may pass the newer void* arguments
                          to old library functions which expect char*, right?
                          Therefore internally it is required that newer void* type have at
                          least the alignment requirement of older char* type in function calls
                          and returns (it still means nothing in context of our discussion, the
                          programmer need not know about this), and of course same representation.


                          [ I think CBFalconer rightfully noticed that the argument in the call:
                          extern char *pc;
                          printf("%p", pc);
                          should be cast to type void* (strictly interpreting the description at
                          the fprintf() function).
                          My intention was to discuss argument passing in variadic functions. So,
                          for the purpose of the discussion, let's assume that printf is actually a
                          user defined function which duplicates standard library printf behaviour,
                          and which internally uses va_* macros from stdarg.h. (We can rename it
                          to my_printf() if you insist.) ]
                          [color=blue]
                          > The interchangeabil ity referred to in the footnote in C99 6.2.5
                          > involves cases where something of one type is interpreted as another,
                          > without a conversion (either explicit or implicit), such as a function
                          > call with no prototype in scope, a call to a variadic function, or a
                          > reference to a union member.[/color]

                          For unions there is no problem: both types have same representation (we
                          agree to it), and the union itself accommodates alignment requirements
                          of all its members.
                          [color=blue]
                          > Suppose void* required 4-byte (word) alignment, but char* only
                          > required 1-byte alignment (I'm referring to the required alignment for
                          > a pointer object). Suppose the compiler has to generate different
                          > code to access a byte-aligned char* than a word-aligned void*. Now
                          > consider your call printf("%p", pc), where pc is a char*. The calling
                          > code pushes the value of pc onto the stack at an odd address (assume
                          > that there is a stack). The code inside printf that accesses the
                          > argument expects a void*, so it uses an instruction that only works on
                          > word-aligned values. Kaboom.[/color]

                          It's a nice explanation (really). But:
                          7.15.1#2 for variadic functions (and similarly 6.5.2.2#6 for functions
                          without prototype) makes special provision for void* and char* types.
                          In order to fulfill it the compiler, when creating a function call, *must*
                          push char* (void*) argument in such a way, that it may be accessed as
                          void* (char*) argument. (In practice that would mean taking at least
                          the least common multiple of both types' alignments.)

                          So, your example still doesn't prove that char* and void* types must
                          have the same alignment, or that the programmer needs know about it.

                          Moreover, passing and argument which is incompatible with parameter
                          (or expected) type, is *explicitly* deemed UB. There is no discussion
                          that we may pass "struct s1*" to where we expect "struct s2*", because
                          their alignments are the same (as you interpret it) and so are their
                          representations . They are incompatible types and it is undefined, period.
                          (If your interpretation is really right, then there must be a flaw in
                          the Standard here.)

                          Therefore, again, there is nothing a programmer gains here by knowing
                          that "pointer to struct" types have same alignment.

                          [color=blue]
                          > [snip][/color]
                          [color=blue]
                          > (I'm not responding to the rest of your message, at least for now,
                          > mostly because I don't have time to do it justice.)[/color]

                          No hurry, I'll be waiting. You'll do me a favour.

                          But maybe there is no point in discussing everything at once. In order
                          to convince me to what is after "Similarly" , first you have to convince
                          me to what the Standard means before the word. I still don't see why
                          void* and char* types should have the same alignment requirements,
                          and that the Standard actually requires it at all.

                          --
                          Stan Tobias
                          sed 's/[A-Z]//g' to email

                          Comment

                          • S.Tobias

                            #28
                            Re: [OT] struct and union alignment

                            Dan Pop <Dan.Pop@cern.c h> wrote:
                            [color=blue]
                            > struct { ... } foo, bar, baz;[/color]
                            [color=blue]
                            > foo, bar and baz are all the objects of this type needed by the program
                            > and they are used in a single translation unit. What would a tag buy you?[/color]

                            I think we're talking of two different things. I used the definition
                            of an anonymous union I found in:


                            Never mind.

                            --
                            Stan Tobias
                            sed 's/[A-Z]//g' to email

                            Comment

                            • S.Tobias

                              #29
                              Re: [OT] struct and union alignment

                              S.Tobias <sNOiSPAMt@amu. edu.pl> wrote:
                              [color=blue]
                              > I think we're talking of two different things. I used the definition
                              > of an anonymous union I found in:[/color]
                              ^^^^^ -> struct
                              (sorry, it's late)

                              --
                              Stan Tobias
                              sed 's/[A-Z]//g' to email

                              Comment

                              • Keith Thompson

                                #30
                                Re: struct and union alignment

                                "S.Tobias" <sNOiSPAMt@amu. edu.pl> writes:
                                [big snip (sorry)][color=blue]
                                > But maybe there is no point in discussing everything at once. In order
                                > to convince me to what is after "Similarly" , first you have to convince
                                > me to what the Standard means before the word. I still don't see why
                                > void* and char* types should have the same alignment requirements,
                                > and that the Standard actually requires it at all.[/color]

                                Just a quick thought. It's entirely possible that the standard is
                                over-specified in this area, and that there's no real advantage in
                                requiring void* and char* to have the same representation and
                                alignment requirements. (I'd have to spend some time thinking about
                                it to decide whether that's the case or not.) Even so, C99 6.2.5p26
                                does require them to have the same representation and alignment
                                requirements, at least according to my interpretation of the text.

                                In order for this to refer to the alignment of what they point to,
                                rather than the alignment of the pointer objects themselves, we'd have
                                to assume that in the phrase "the same representation and alignment
                                requirements", "representation " refers to the pointers (since there is
                                no representation for void), and "alignment requirements" refers to
                                the alignment of what's being pointed to. I suppose that's not
                                entirely unreasonable, since even in this sense the "alignment
                                requirements" of a pointer are arguably a property of the pointer
                                itself.

                                But we already know the alignment requirements of what void* and char*
                                point to: both types have to be able to refer to any byte in any
                                object. An additional explicit statement to that effect in 6.2.5p26
                                would be logically redundant (rather than just possibly unnecessary).
                                The only way 6.2.5p26 makes sense to me is if it refers to the
                                alignment requirements for char* and void* objects, not for what they
                                point to.

                                Here's a (rather silly) program that, I believe, is guaranteed to work
                                given the requirement in 6.2.5p26, and wouldn't be guaranteed to work
                                without it:

                                #include <stdio.h>
                                int main(void)
                                {
                                char obj;
                                char *c_ptr = &obj;
                                void *v_ptr;

                                v_ptr = *((void**)&c_pt r);

                                printf("c_ptr = %p\n", (void*)c_ptr);
                                printf("v_ptr = %p\n", v_ptr);
                                return 0;
                                }

                                It assigns the value of c_ptr to v_ptr by pretending that there's a
                                void* pointer object in the location of c_ptr. There's no char* to
                                void* conversion, implicit or explicit, so the compiler doesn't have a
                                chance to allow for any difference in representation or alignment. If
                                we used an int* rather than a char*, 6.2.5p26 wouldn't apply and we'd
                                have undefined behavior; int* and void* needn't even be the same size.

                                (gcc with too many warnings enabled complains that "dereferenc ing
                                type-punned pointer will break strict-aliasing rules".)

                                --
                                Keith Thompson (The_Other_Keit h) kst-u@mib.org <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.

                                Comment

                                Working...