osd@hou2d.UUCP (Orlando Sotomayor-Diaz) (07/30/85)
From: Orlando Sotomayor-Diaz (The Moderator) <cbosgd!std-c> mod.std.c Digest Tue, 30 Jul 85 Volume 8 : Issue 16 Today's Topics: C.1.2.5 Types query on varargs and assert Section C.5.1: 'first' vs. 'non-excess' register variables Some comments on some recent mod.std.c articles (2 msgs) ---------------------------------------------------------------------- Date: 14 Jul 85 05:15:25 CDT (Sun) From: ihnp4!utzoo!henry Subject: C.1.2.5 Types To: lsuc!msb > ... It seems to me that the void type is semantically an empty > enumeration, yet enumerations are classified as derived types and > void isn't ... the other derived types are defined in terms of > the basic types (or other derived types), and enumerations are not. If you look carefully, you will see that enums are *not* a primitive type; they are a way of giving names to integer constants. If enums were like Pascal enumerated types, your suggestions would be good. (Whether one agrees with the integer-constants semantics of enums is another story, and I understand there was a major war within the committee about this.) > ... It appears to me that this [C.1.2.5] > implies that a char is guaranteed to be equivalent to one of signed > char and unsigned char, rather than different from either. > > I suggest that, for clarity's sake, this should be stated explicitly > either in a note or in the text proper... Earlier drafts did say that char was equivalent to either signed char or unsigned char; they were wrong. Note that widening char gives an int, even if chars are always positive, while widening an unsigned char used to give an unsigned. I haven't analyzed the effects here of the revised widening rules; it is possible that you are now correct. Henry Spencer @ U of Toronto Zoology {allegra,ihnp4,linus,decvax}!utzoo!henry ------------------------------ Date: Sun, 21 Jul 85 21:33:04 edt From: decvax!minow (Martin Minow) Subject: query on varargs and assert To: std-c@cbosgd hcr!lsuc!msb asks in V8#11 why the variable arguments macros must be defined as macros, and not as functions. The reason is that the argument to va_start, va_arg, and (probably) va_end is accessed by reference, and not by value. Also, since one of the parameters to va_arg is a type name, you can't really pass it to a function without some modification: foo(int) will yield a syntax error. A sample implementation (say, for the PDP-11 or some other simple machine) would be nice. The following is a guess -- and hasn't been tested: #define va_list(ap) char *ap; #define va_start(ap, n_ptrs) (ap = ((char *) &n_ptrs) + sizeof (n_ptrs)) #define va_arg(ap, type) (((type *) (ap += sizeof(type)))[-1]) #define va_end(ap) Assert must be defined as a macro in order to obtain correct values for __LINE__ and __FILE__, if for no other reason. Martin Minow decvax!minow ------------------------------ Date: Sun, 14 Jul 85 09:49:48 edt From: Kevin Martin <ihnp4!watmath!kpmartin> Subject: Section C.5.1: 'first' vs. 'non-excess' register variables To: lsuc!msb >From: hcr!lsuc!msb (Mark Brader) >This says: "... excess register declarations are treated as auto declarations." >This is less specific than K&R, which states that "only the FIRST few" >register declarations are effective. The sentence should be rephrased >to state that if there are more register declarations than an implementation >allows then the ones that will be accepted will be the first ones. On machines with registers dedicated to specific types, this would be impractical. For example, on a machine which has room for 4 register pointers, but no register integral types, the following declarations would give no variables in registers under your scheme: register int i; register char *p, *q; I would prefer it if this paragraph were as vague as possible. Otherwise, there may be implementations which can't do a good job with 'register' declarations because the standard won't allow it. I would prefer the following wording for the paragraph describing 'register' variables: "A declaration with storage-class specifier 'register' is an 'auto' declaration with a suggestion that the objects declared will be frequently used, as well as a promise that no attempt will be made to access the object by indirecting through a pointer (however obtained). The unary '&' (address-of) operator must not be applied to such an object. The treatment of such objects by the compiler is implementation-defined; however, it frequently involves storing such objects in fast storage, such as machine registers. When making such optimizations, the compiler should give preference to objects in the order in which they are declared. Note: The most common form of 'register' variable optimization is the assignment of a limited number of objects to specific machine registers for the entire duration of their scope." This wording means that on your Vaxen, PDP-11's, etc. you get the current behaviour. But this wording also allows optimization on non-general-register machines, since it does not require that the object be kept in a register for its *entire* scope. Either way, it still gives preference to the initial 'register' declarations, which is what Mark wanted. Kevin Martin, UofW Software Development Group ------------------------------ Date: 14 Jul 1985 0655-PDT (Sunday) From: ucbvax!kre (Robert Elz) Subject: Some comments on some recent mod.std.c articles To: ihnp4!utzoo!lsuc!msb Subject: C.2.1.2 Signed and unsigned integers It appears as if this section was attempting to say when conversions take place, as well as how the conversion is done - the modified wording suggested omits that. Subject: C.3.2.1 Array subscripting > Is it really appropriate for the standard to speak of "usual" things? > C.3.2.1 says that a[b] is "usually" array[integer]. The definition of 'a[b]' as *(a + b) is all that's needed as a definition, the properties and requirements of the '*' and '+' operators supply all that is needed. However, relying on that alone might tend to be confusing to many readers. I doubt that supplying an example of the "usual" case does any harm. Subject: C.3.3.2 Address and indirection operators > "If an invalid value has been assigned to a pointer, the behavior of the > unary * operator is undefined. Such invalid values include ... a pointer > to void." > This should be rephrased to eliminate the conflict with C.2.2.3, Pointers, > which says: "A pointer to an object of any type may be converted to a > pointer to void ... and back again without change." I don't see any conflict - the paragraph quoted above merely says that unary * is undefined. How does that conflict with the notion of converting a (void *) back to a (foo *) ?? Robert Elz ucbvax!kre ------------------------------ Date: Thu, 18 Jul 85 01:51:17 edt From: hcr!lsuc!msb Subject: Some comments on some recent mod.std.c articles To: utzoo!ihnp4!ucbvax!kre Subject: C.2.1.2 Signed and unsigned integers > It appears as if this section was attempting to say when conversions > take place, as well as how the conversion is done - the modified > wording suggested omits that. It was meant to. When conversions take place is covered elsewhere. Subject: C.3.2.1 Array subscripting > > Is it really appropriate for the standard to speak of "usual" things? > > C.3.2.1 says that a[b] is "usually" array[integer]. > ... I doubt that supplying an example of the "usual" case does > any harm. Fair enough, but I think it should be a note. Certainly a minor point. Subject: C.3.3.2 Address and indirection operators > > "If an invalid value has been assigned to a pointer, the behavior of the > > unary * operator is undefined. Such invalid values include ... a pointer > > to void." > > This should be rephrased to eliminate the conflict with C.2.2.3, Pointers, > > which says: "A pointer to an object of any type may be converted to a > > pointer to void ... and back again without change." > I don't see any conflict - the paragraph quoted above merely > says that unary * is undefined. How does that conflict with > the notion of converting a (void *) back to a (foo *) ?? I think the quoted C.3.3.2 paragraph implies that c2 is undefined after extern char c; char c2; void *vp; vp = &c; cp = vp; c2 = *cp; ... because the second assignment assigned a pointer-to-void to cp. But the quoted C.2.2.3 paragraph says that it is defined, because the pointer was copied back to the same type; c2 will equal c. { decvax | ihnp4 | watmath | ... } !utzoo!lsuc!msb also via { hplabs | amd | ... } !pesnta!lsuc!msb Mark Brader and uw-beaver!utcsri!lsuc!msb ------------------------------ End of mod.std.c Digest - Tue, 30 Jul 85 08:26:15 EDT ****************************** USENET -> posting only through cbosgd!std-c. ARPA -> ... through cbosgd!std-c@BERKELEY.ARPA (NOT to INFO-C) In all cases, you may also reply to the author(s) above.