develooper Front page | perl.perl5.porters | Postings from June 2010

Re: ANSI requirement

Thread Previous | Thread Next
Aaron Crane
June 12, 2010 03:42
Re: ANSI requirement
Message ID:
Ævar Arnfjörð Bjarmason <> wrote:
> I vaguely recall someone mentioning that we rely on some features of C
> that aren't strictly guaranteed by ANSI C, such as the the offset into
> a struct being the sum of the sizeof() of the struct members that came
> before in the struct.

As others have said, it'd be pretty surprising if we were relying on
that specifically; we'd almost certainly get some icky bugs on most
platforms if so.

However, given the vagueness of your recollection, it's possible that
you're thinking of the fact that we *do* rely on the "struct hack",
which involves structure definitions of the form

  struct foo {
      size_t len;
      unsigned char buf[1];
  } *foo;

The intention of such structures is that `foo->buf` is a
variable-length array; the whole thing is allocated with malloc or
similar, with a calculated size that is the sum of `sizeof(struct
foo)` and the desired length of the array.  The alternatives in C89
all involve overhead in either space or speed (or both).

A quick grep suggests that we have such constructs in hv.h (twice),
os2/os2ish.h (several times), and regcomp.h (several times).

Programs containing this construct are *not* considered to be
strictly-conforming ANSI/ISO C; Dennis Ritchie has allegedly referred
to the technique as "unwarranted chumminess with the C implementation"
(and a variant of that phrase crops up in a comment on one of the
occurrences in regcomp.h).  However, I'm not aware of anyone ever
pointing to a widely used compiler which handles such code other than
intended, or why (modulo perhaps strict-me-harder run-time bounds
checking) anyone would build such a compiler for any machine with a
half-way sane memory model).  And given the popularity of the
technique (Perl is by no means the only large application to do it),
that seems likely to remain true indefinitely.

Nonetheless, adding a note to INSTALL mentioning that we use the
struct hack seems reasonable to me.

As it happens, C99 adds "flexible array members" as a
standardly-blessed way of achieving the same end; you declare the
flexible member with empty square brackets, and the structure is then
considered an incomplete type (so you can't declare an object of that
type, or take its size with sizeof).  If someone were interested, I
think a little configure probing and preprocessor macrology could
arrange for C99-capable compilers to use flexible array members in
place of the struct hack in the Perl source.

A little more information on the struct hack can be found here:

Aaron Crane **

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About