[mod.std.c] mod.std.c Digest V8#16

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.