🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c
Article #2207

Re: struct hack

#2207
From: Mark Brader
Date: Wed, 07 Oct 1992 00:14
47 lines
2805 bytes
> I have been following this thread for a while, and since nobody else
> seems to have said it, I will.
> 
> >     struct fred { int i; char s [1]; } *f;
> >     char *s;
> > 
> >     /* ... */
> >     f = malloc (sizeof f + strlen (ss));
> >     f->s[1 /* or 2, or anything other than 0 */] ;
> 
> ... As is pointed out in previous posts, the pointer returned by malloc
> points to an area big enough for the job.  In fact, the following
> should be legal:
> 
>     char *p = malloc( sizeof( struct fred ) + strlen( ss ) ) ;
>     p += offsetof( struct fred , s ) ;
>     p[ 1 /* Or anything up to the end of the malloced memory */ ]
> 
> The problem with the example is that the pointer under consideration
> is *not* the pointer returned from malloc, but rather the results of
> the pointer expression f->s (which has a type of char*).

Correct, but this does not affect the relative legality of the two
expressions.  The standard says in 3.1.2.5 (ANSI, 6.1.2.5 in ISO) that
a value of pointer type "provides a reference to an entity of the
referenced type".  That is, a char * points to ONE char.  Whether that
char happens to be part of a larger object is irrelevant; this fact
cannot be represented in the type.  Suppose the above examples to be
modified so that f and p are initially copies of the same value returned
by a single call to malloc(), with the subsequent operations the same.
The expressions p and f->s point to the same char; therefore they are
wholly identical; assuming that strlen didn't return 0, p[1] is legal;
therefore, under the same assumption, f->s[1] is legal.

The restrictions in 3.3.6 (6.3.6) that allow bounds checking are on
the additive operators (and therefore implicitly on subscripting, of
course).  They are expressed in terms of whether the operand pointer
value and the resulting value point to elements of the same array or
not; there is nothing about HOW the operand value pointing into that
array was obtained in the first place.  In this case the values do
point to elements of the same array, namely the malloc()ed one.  QED.
-- 
Mark Brader		  "Should array indices start at 0 or 1?  My ecumenical
SoftQuad Inc., Toronto	   compromise of 0.5 was rejected without, I thought,
utzoo!sq!msb, msb@sq.com   proper consideration."  -- Stan Kelly-Bootle

This article is in the public domain.
Technical Details
Message-ID: <1992Oct7.001450.16021@sq.sq.com>
Path: arc1-ca.pugleaf.net!sparky!uunet!uunet.ca!wildcan!sq!msb
References: <1992Sep10.153316.20804@awdprime.austin.ibm.com> <1992Sep19.225457.13353@jarvis.csri.toronto.edu> <KANZE.92Oct2210740@slsvdnt.us-es.sel.de>

Show Full Headers
Complete Article Headers
Newsgroups: comp.std.c
Path: arc1-ca.pugleaf.net!sparky!uunet!uunet.ca!wildcan!sq!msb
From: msb@sq.sq.com (Mark Brader)
Subject: Re: struct hack
Message-ID: <1992Oct7.001450.16021@sq.sq.com>
Organization: SoftQuad Inc., Toronto, Canada
References: <1992Sep10.153316.20804@awdprime.austin.ibm.com> <1992Sep19.225457.13353@jarvis.csri.toronto.edu> <KANZE.92Oct2210740@slsvdnt.us-es.sel.de>
Date: Wed, 7 Oct 92 00:14:50 GMT
Lines: 47