doubtful assumptions about pointers

Doug Gwyn gwyn at smoke.BRL.MIL
Tue Jan 16 15:01:40 AEST 1990


In article <1259.25ae2019 at csc.anu.oz> bdm659 at csc.anu.oz writes:
>Don't put words into my mouth.

I didn't necessarily mean to imply that this was YOUR motivation,
but many similar discussions in the past have been based on such
a formalist/rationalist point of view (to be charitable to them).

>Forgive me if my memory is wrong, but I seem to remember a posting of yours
>in which you agreed that the members of unions might not physically overlap
>in some implementations.  If you consider that pi might point to such a member,
>there are difficulties in reconciling that posting with this one.

Union members "overlap".  In order to implement some forms of union
on some unusual architectures, it may be necessary to use storage areas
for different members that don't actually overlap.  Nevertheless, it
still conceptually is an overlap, and any program that assumes that
one member value is unaffected upon storing into another member is not
strictly conforming.

This consideration doesn't affect the specific example of an int being
accessed via a converted char pointer.

An implementation may have some bits in its representation of an int
that are "unused", and therefore modifying a part of the int via a
char pointer might happen to not affect the represented value, depending
on just where into the int representation the char* points.  Assuming
either that the value will be changed or that it won't be changed by such
an operation also makes a program not strictly conforming.

>...  We are only given some functional axioms, from which
>some desirable properties, like this one, don't obviously follow.

Well, you know what I said about excessive rationalism.
This was one example where an implementation could technical strictly
conform without having the desirable property.  As I said, I don't
expect this to be a practical problem.

The category "RA" would fit this and some others that I labeled "TA"
when I meant "expected to be TA in practice, although not strictly
logically deducible from the Standard's specifications".

>Why does equal representation imply equal semantics?

It doesn't, but if you think about how the implementation must use
the representations in testing for pointer equality, it should be
apparent that when two char*s compare equal, the corresponding
void* conversions should compare equal.  Again, a truly perverse
implementation could possibly go out of its way to cause this to
fail, but since it is harder to do that than to do it the obvious
way, I also don't expect this to be a problem in practice.  "RA"

>An argument based on the existence of functions like memcpy() might show
>DA[2] is an RA, though.

Certainly memcpy() indicates what X3J11 thought void*s were supposed
to be useful for.

>Actually i is nonzero, though your argument still holds.  However, the case
>with i==0 is a more instructive DA (indeed FA as you say).

Oops.

>Anyway, alignment is defined as a requirement on objects; applying it
>to the values of pointers which may not be pointers to objects seems
>doubtful.  As far as implementations are concerned, consider one which
>treats pointers of kind P3 as a special case in representation (perhaps
>to permit objects reaching to the end of memory segments).  It may be
>that making (int*)(char*) a no-op in this case could take more work,
>not less.

It would require a general slowdown in pointer operations to represent
the P3 case in a manner not uniform with other object pointers.  In any
case, I would expect such an implementation to apply the same sort of
local flat address space linearization that it must do for pointer
arithmetic to the conversion of pointers.  Since the size of an array
includes padding, the "last+1" element of an array meets the same
alignment constraints as the other array elements.  "RA"

>You missed my point.  Suppose the body of the text said "Gismos are pink."
>and the footnote said "This is meant to imply that gismos are pink and
>crinkly.".  What can we infer about gismos?  Well, the only reasonable
>inference is that gismos are both pink and crinkly, even though the footnote
>is not supposed to be part of the standard.

To me, this supports what I said about the problems introduced when
one resorts to formalistic reasoning.  You CANNOT understand a concept
by merely substituting its definition for all linguistic uses of the
concept.  A concept in general subsumes more than the definition would
imply; there are other relevant properties.

When the Standard says that two types have the same representation and
alignment requirements, it means that IN ALL CONTEXTS they have the
same r&a requirements.  That does imply what footnote 15 says; the
footnote was added as a result of public review comments because we
kept getting asked "Does this also mean when used as function arguments?".

Note that there may be different contextual r&a requirements for the
same type used as:
	static
	automatic
	register
	volatile
	string literal
	function argument
	function parameter
	function return value
and in still other contexts.  A context-free constraint on r&a
requirements must be applied appropriately in all contexts.

>from the Forward: "[pANs] addresses the problems of both the
>program developer and the translator implementor by specifying the
>C language precisely."   Are you saying it fails to meet this claim?

Precision is a matter of degree.  The ANSI Standard is considerably
more precise than K&R Appendix A.  It need only be sufficiently
precise to fulfil its role as reference treaty between programmer
and implementor.

>I wish to test things for strict conformity by applying the definition that
>the standard gives.  If it isn't "specified in this Standard", it isn't
>strictly conforming.

Conformance tests should not flag behavior as a violation if it is not
possible to relate it to explicit wording in the Standard, even if it
is insane behavior, if the result of such testing might end up in
litigation.  These "RA" cases deserve to be uncovered, however, since
many applications are and will be assuming reasonable implementations
and the programmer should hear about it if an implementation goes out
of its way to introduce unwarranted obstacles.

>(2) One person's "perverse" is another person's "reasonable".

My notion of a perverse implementation is one that deliberately
exploits an ambiguity in the specification, with considerably more
effort than would be required to implement "reasonable" behavior
such as would be expected by experienced C programmers, to force
portable programs to use complex code to avoid triggering the
perverse behavior.  If someone else thinks such an implementation
should be deemed reasonable, he's disconnected from the real world
of computer programming.

This does not include reasonable implementation choices that are
forced by the architecture or environment, just those for which
there is no good reason.

As an example of how an implementation can be perverse, suppose that
a POSIX implementation really literally obeyed the last word of the
specification in IEEE Std 1003.1-1988 section 8.2.3.4.  While that
would be literal conformance to the specification, and while a
reasonable implementation would have to violate that part of the
specification, it would nevertheless be perverse to obey that spec,
which is obviously an error due to incomplete editing of text copied
from scetion 8.2.3.2.



More information about the Comp.std.c mailing list