home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #31 / NN_1992_31.iso / spool / comp / std / c / 3319 < prev    next >
Encoding:
Internet Message Format  |  1993-01-03  |  3.0 KB

  1. Path: sparky!uunet!usc!rpi!crdgw1!rdsunx.crd.ge.com!bart!volpe
  2. From: volpe@bart.NoSubdomain.NoDomain (Christopher R Volpe)
  3. Newsgroups: comp.std.c
  4. Subject: Re: Struct hack one last time (one last time)
  5. Message-ID: <1993Jan3.224501.9742@crd.ge.com>
  6. Date: 3 Jan 93 22:45:01 GMT
  7. References: <1992Dec31.153931.7495@hubcap.clemson.edu> <1993Jan1.173852.26630@taumet.com> <1993Jan2.072908.21929@sq.sq.com>
  8. Sender: volpe@bart (Christopher R Volpe)
  9. Reply-To: volpe@ausable.crd.ge.com
  10. Organization: GE Corporate Research & Development
  11. Lines: 62
  12. Nntp-Posting-Host: bart.crd.ge.com
  13.  
  14. In article <1993Jan2.072908.21929@sq.sq.com>, msb@sq.sq.com (Mark Brader) writes:
  15. |> > > [Is] the notorious "struct hack" was still conformant if the tail array
  16. |> > > in the struct [is] of type other than char[?] ... My reading of the
  17. |> > > earlier thread on this topic was that the hack was indeed legal, but
  18. |> > > all the previous examples used an array of char in their examples.
  19. |> > > Thus, is there any reason it would not be legal to declare:
  20. |> > >    struct vector {
  21. |> > >        int  size;
  22. |> > >        double v[1];
  23. |> > >    } *vec;
  24. |> > > and then code (for example):
  25. |> > >    vec = malloc(sizeof(struct vector) + (n - 1) * sizeof(double));
  26. |> > >    vec->size = n;
  27. |> > >    for ( i = 0;  i < vec->size;  i++ )  vec->v[i] = 0.0;
  28. |> 
  29. |> I previously believed that this code was indeed legal, but I have lately
  30. |> come to the opposite opinion.  Return to the classic struct hack:
  31. |> 
  32. |>     struct hack /* well, what else? */ {
  33. |>         int len;
  34. |>         char arr[1];
  35. |>     } *p;
  36. |>     p = malloc(sizeof(struct hack) + n-1);  /* where n > 1 */
  37. |> 
  38. |> In this, access to p->arr[1] is legal because p->arr decays to a
  39. |> pointer which points to some element of the object returned by
  40. |> malloc -- you can identify which one by using offsetof -- and
  41. |> the pointer p->arr+1 also points to some element of this object,
  42. |> thus meeting the requirement specified by 3.3.6/6.3.6.
  43.  
  44. Agreed.
  45.  
  46. |> In the other example using double, we still know that the pointer
  47. |> obtained by decay of vec->v points to a double which is somewhere
  48. |> within the object returned by the malloc(), but we do NOT know that it
  49. |> points to a double that would be an element of that object if we viewed
  50. |> it as an array of doubles.  And this distinction, I fear, is critical.
  51.  
  52. Ah! But is that necessary? I don't think so. As long as it points to a double
  53. that would be an element of that object if we viewed it as an array
  54. of SOMETHING. Suppose we viewed the malloced storage as an array of
  55. the following structs:
  56.   
  57.   struct vec2 {
  58.     int size;
  59.     double v[2];
  60.   }
  61.  
  62. The above struct has one more element in the "v" field than the one
  63. in question. Thus, even though &vec->v[1] may not point to a double that
  64. would be an element of the malloced storage if viewed as an array of
  65. doubles, it *would* point to a double that would be a (component of) an
  66. element of the malloced storage if viewed as an array of "struct vec2". 
  67. Thus, the legitimacy of the struct hack is restored.
  68.  
  69. -Chris
  70.  
  71. -- 
  72. ==================
  73. Chris Volpe
  74. G.E. Corporate R&D
  75. volpecr@crd.ge.com
  76.