home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / std_unix / volume.17 / text0094.txt < prev    next >
Encoding:
Internet Message Format  |  1990-01-06  |  3.9 KB

  1. From: Mark Brader <uunet!sq.sq.com!msb>
  2.  
  3. Well, I've just seen the same topic being discussed independently in three
  4. different newsgroups, with three different Subject lines (four, now...).
  5. I've cross-posted this article to all three groups, and directed followups
  6. to comp.std.c; I suggest that further followups on the topic be made from
  7. this article (to keep the same Subject line), and in that group unless
  8. they refer specifically to existing C implementations or to POSIX.
  9.  
  10. The issue is the legality of:
  11.  
  12.     struct foo_struct {
  13.     int bar;
  14.     char baz[1];
  15.     } *foo;
  16.  
  17.     foo = (struct foo_struct *) malloc(sizeof(struct foo_struct)+1);
  18.     foo->baz[1] = 1;  /* error? */
  19.  
  20. [Note that it is not disputed that, if this IS done, an assignment of
  21. *foo to another struct foo_struct won't copy the entire contents of the
  22. "extended" baz member; for this reason if no other, the construct may
  23. be undesirable.]
  24.  
  25. Both Doug Gwyn and Dennis Ritchie have recently stated without proof,
  26. unless I misunderstood them, that this is not safe.  I believe Doug has
  27. stated that there are implementations where it doesn't work, but hasn't
  28. named any.  Can someone do so (in comp.lang.c)?
  29.  
  30. A second issue is whether the usage is in conformance with the proposed
  31. ANSI Standard (pANS) for C.  I claim that it is.
  32.  
  33. The article from which the above code was taken continues:
  34.  
  35. > Note that it is provable that the char pointer (foo->baz + 1) points
  36. > within the object returned by malloc.
  37.  
  38. (The + here is of course the one derived from replacing x[y] with *(x+(y)).)
  39.  
  40. To this another poster replied (in an article that was for some reason
  41. posted with Distribution usa, but which made it here anyway):
  42.  
  43. | Unfortunately, it is not provable that the char pointer(foo->baz + 1)
  44. | points within the sub-object baz.  Hence, the behavior is undefined
  45. | (X3J11/88-158, 3.3.6, page 48, lines 24-27). 
  46.  
  47. But this, I say, is irrelevant.  I'll quote the actual words:
  48.  
  49. # Unless both the pointer operand and the result point to elements of
  50. # the same array, or the pointer operand points one past the last element
  51. # of an array object and the result points to an element of the same array
  52. # object, the behavior is undefined if the result is used as an operand
  53. # of the unary * operator.
  54.  
  55. There is NO REQUIREMENT here that the "array" spoken of, and the array
  56. whose name was mentioned in the pointer operand, be the same.  In this
  57. case the pointer operand (char pointer value foo->baz), and the result
  58. (foo->baz + 1), both point into the space returned by malloc() which, it
  59. is guaranteed, may be treated as an array of sizeof(struct foo_struct)+1
  60. chars.  So they do point into the same array.
  61.  
  62. Section 4.10.3, page 155, lines 13-15 (gee, this sounds familiar):
  63.  
  64. # The pointer returned ... may be assigned to a pointer to any type of
  65. # object and then used to access such an object or an array of such
  66. # objects in the space allocated ...
  67.  
  68. Well, to be fair, we didn't literally do that.  To do it literally,
  69. we would have had to do:
  70.  
  71.     char *fooc = (char *) malloc(sizeof(struct foo_struct)+1);
  72.     fooc += offsetof (struct foo, baz);      /* sets fooc to foo->baz */
  73.     fooc[1] = 1;                 /* error? */
  74.  
  75. Is anyone claiming that fooc in the last line of this code could have
  76. a different value from foo->baz in the original?  If not, can anyone
  77. cite another reason why this code is not conforming?  Offsetof is a macro
  78. defined in section 4.1.5, page 99, lines 24-30, of which the key part is:
  79.  
  80. # offsetof(type, memberdesignator) ... expands to an integral constant
  81. # expression ... the value of which is the offset in bytes, to the structure
  82. # member ..., from the beginning of the structure ...
  83.  
  84.  
  85. -- 
  86. Mark Brader    "Either the universe works in a predictable, analyzable way
  87. Toronto         or it works spasmodically, with miracles, action at a distance
  88. utzoo!sq!msb     and wishful thinking as the three fundamental forces.  People
  89. msb@sq.com     tend to take one view or the other."    -- Frank D. Kirschner
  90.  
  91. This article is in the public domain.
  92.  
  93. Volume-Number: Volume 17, Number 104
  94.  
  95.  
  96.