comp.lang.ada
 help / color / mirror / Atom feed
From: "David Thompson" <david.thompson1@worldnet.att.net>
Subject: Re: type Foo_ptr in new void*;
Date: Sat, 04 Aug 2001 06:05:05 GMT
Date: 2001-08-04T06:05:05+00:00	[thread overview]
Message-ID: <lgMa7.1810$1p1.135991@bgtnsc04-news.ops.worldnet.att.net> (raw)
In-Reply-To: 3B663A70.3B315EC8@san.rr.com

Darren New <dnew@san.rr.com> wrote :
...
> > Since [sizeof a C incomplete struct type namely Foo] is
> > undefined, there is no correct answer to that question. Without a
> > proper definition of the sizeof Foo, there can be no reliable pointer
> > arithmetic.
>
> Right. That's why you can't do pointer arithmetic on a Foo* without
> defining Foo.
>
One thing the previous poster might have been thinking of is
that in C89/90 you could _declare_ as "extern" an array of
an incomplete type; you might also be able to declare/define
a function (formal) parameter as array of incomplete since
that can be "adjusted" to a pointer, and pointer to incomplete
is fine, although the WG response to Defect Report 047 held
that this is not guaranteed; you could also define a typedef
for array-of-incomplete if ultimately used only as above.
You could _define_ (allocate) an actual array object only
with a complete element type.

Since you can't do pointer arithmetic (and thus []) on it,
the only thing you could do with an array-of-incomplete
was pass its address (pointer) to some other code which
_does_ know about the completed type.

In C99, this feature(?) is gone; it is now a constraint (6.7.5.2p1)
on the array declarator that the element type must be complete
in all cases, and thus a required diagnostic if not (see below).
(But even when compilers start supporting C99, I expect some,
maybe many, will still have options to get C89 behavior.)

> Which is not to say that Ada isn't superior to C in this respect.
>
In particular, in C it is the programmer's responsibility to have
different translation units (roughly, source files) use identical
definitions (or nearly so) for a struct type.  It is easy to get this
wrong; the implementation is not required to detect it; and
many, probably most, don't, since the compile+link model
doesn't normally support it, although it would be legal.
(I do know one implementation where the linker checks
that function parameters which are pointers agree on
the _size_ of the target; this doesn't catch all errors,
but does help a good bit.  I think it does so primarily
because it needs this info in the object file for Fortran
and COBOL, and C goes along for the ride.)

Actually writing different definitions in two different sources
is fairly obvious, but there are subtler ways to screw up.
One is to change the definition in a .h file and recompile
some but not all of the .c's that use it; tools like make
help with this.  Another is to have two same-named .h files
in different directories/subtrees and select a wrong one.
A third is to actually include the correct and same .h
but it in turn uses #define's which are set differently
(a coworker recently lost several days to that last;
even a full de novo build doesn't catch or fix it).

> But what do you think a compiler is going to do if you index an array of
> Foo without defining Foo? Just randomly make up a sizeof(Foo) from whole
> cloth? There's probably something in the standard about this.
>
If anyone really cares (from C99 = ANSI/ISO/IEC 9899:1999)
- 6.5.2.1 defines subscripting (partly) in terms of pointer addition
- 6.5.6p2 requires in a constraint that (one) operand of pointer addition
be "to an object type"
- 6.2.5p1 defines "object type" to exclude incomplete types.
(Those places in the standard that want to allow incomplete types
say "object or incomplete type".)
- 6.5.3.4p1 requires in a constraint that sizeof "shall not be applied to
... an incomplete type ..." (sizeof is not actually used in the _definition_
of pointer arithmetic directly, although that's the usual implementation,
only indirectly through 6.2.5p20 array elements are contiguous)
- 5.1.1.3 requires "at least one diagnostic message" if there is
"a violation of any syntax rule or constraint" -- although the standard
doesn't require _useful_ diagnostics; it is only a nonnormative footnote
that it _should_ "identify the nature of, and where possible localize,
each violation."

Having diagnosed a violation, the implementation is permitted
to do anything whatsoever, even continue to translate and execute;
this is Undefined Behavior "on which this International Standard
imposes no requirements" (much like Ada Unbounded Error).
If a compiler writer was silly enough to think that a random (more
likely pseudorandom) sizeof here was a good idea, they could.
More plausible is to just use whatever value happens to be in
some slot of the symbol table that would be correct for a
complete type but isn't valid (wasn't set) for incomplete.

HAND.
--
- David.Thompson 1 now at worldnet.att.net








  reply	other threads:[~2001-08-04  6:05 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-07-29  4:31 type Foo_ptr in new void*; Tomasz Wegrzanowski
2001-07-29  5:56 ` tmoran
2001-07-29  8:57   ` Tomasz Wegrzanowski
2001-07-29 12:26     ` Marc A. Criley
2001-07-30  1:05       ` Tomasz Wegrzanowski
2001-07-30  1:20         ` tmoran
2001-07-30  2:09         ` James Rogers
2001-07-30  2:36           ` Warren W. Gay VE3WWG
2001-07-30  3:10             ` James Rogers
2001-07-31  2:14               ` Warren W. Gay VE3WWG
2001-07-31  1:21           ` Tomasz Wegrzanowski
2001-07-31  3:06             ` James Rogers
2001-07-31  5:02               ` Warren W. Gay VE3WWG
2001-07-31  7:22               ` Florian Weimer
2001-07-31  4:56           ` Darren New
2001-08-04  6:05             ` David Thompson [this message]
2001-08-05  2:27               ` Warren W. Gay VE3WWG
2001-07-29 13:40     ` Dale Stanbrough
2001-07-29 14:12 ` Florian Weimer
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox