Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!yale!cmcl2!lanl!jlg From: jlg@lanl.gov (Jim Giles) Newsgroups: comp.lang.misc Subject: Re: C's sins of commission Message-ID: <65680@lanl.gov> Date: 13 Oct 90 03:51:19 GMT References: <26296@megaron.cs.arizona.edu> Organization: Los Alamos Natl Lab, Los Alamos, N.M. Lines: 73 From article <26296@megaron.cs.arizona.edu>, by gudeman@cs.arizona.edu (David Gudeman): > [...] > An int, on the other hand, is a variable whose _value_ is a > bit-string. But, bit-strings aren't particularly important to me. I > almost never need to know or manipulate them in any way. So why do I > need a data type who's values are bit-strings? Here we see the basic confusion between the semantics of something and its implementation. The _value_ of an int is an integer restricted to some limited range (machine dependent - unfortunately). The internal representation _may_ be a bit string. On the other hand, the representation _may_ be a string of decimal digits (which in turn _may_ be implemented as bit strings), or the value _may_ be represented as trits (which I assume is the name one would give to the basic units of tri-state logic designs). Which of these (or any other) internal representations I get is (or at least, should be) irrelevant to me. > [...] > The above probably won't make the point (though it should) so I will > expand on it. A pointer might have an address as its concrete value, > but you should be thinking of a pointer as an abstraction, not by its > concrete representation. A pointer is a data type with certain > operations on it: And, if the equivalent functionality can be provided in a different for which gives the user more control over the semantics while allowing the compiler greater freedom in choosing the internal representation, why not prefer it? > [...] > for pointers declared "TYPE *p, *q", the following > *p returns an l-value referencing an object of type TYPE (as > for any other data object, if p is not initialized the > outcome of any operation is undefined) And, for non-pointers declared TYPE p, q, the following p returns an l-value referencing an object of type TYPE As for any other data object, the default initial value should be required to be specified either by the definition of TYPE itself, or by initialization within the declaration of each variable - with the later overriding the former if both initializations are present. The only exception to this is in the case of dynamically allocated variables, in which case, the allocation mechanism should always initialize. > [...] > p + i returns a pointer to the ith element of type TYPE > following *p. This is only valid if there is a contiguous > sequence of at least i elements of type TYPE following *p. If p is to be used as an indexed object, it should be declared as such. Either an array or a sequence specification in the declaration of p should be required. That way, both the user and the compiler are aware of the bounds, extent, and rank over which the object is indexed. > [...] > p < q returns TRUE iff *p preceeds *q in a sequence of > elements of type TYPE, assuming that both *p and *q are > members of the same contiguous sequence. The same applies to indexes within arrays or sequences. With the added advanntage that the fact that both indexes apply to the same contiguous sequence of values is explicit in every use - so both the user and the compiler can make precise assumptions about this property. The issue isn't whether pointers have properties which can be abstracted from raw addresses or not. The issue is whether the properties of pointers are required (or even desireable) in the context of a high-level language. J. Giles