[comp.lang.c] structure enhancements

andrew@teletron.UUCP (Andrew Scott) (10/15/87)

I'm not really up on what the ANSI C committee is doing, and these topics
may have been discussed before (although I haven't seen them), but I'd like
to toss out a few ideas on "things I'd like C to do" for discussion:

1. structure equality/inequality operators

	I'd like to see the == and != operators apply to structure variables.
If structure assignments are allowed (as they are in many compilers), why not
allow (in)equality operators also?

2. appropriate bitfield sizing

	It would be convenient if one could specify how much space a bitfield
structure was stored in (instead of always defaulting to int).  I'd like to be
able to do things like this:

	struct message {
		struct {
			unsigned type : 2;
			unsigned ack : 3;
			unsigned seq : 3;
		} header;
		char text[253];
		short crc;
	};

The intent is for the 'header' to be stored as an 8 bit quantity.  Without this,
I declare 'header' as a char and use masks to extract specific fields.  Yuk.
It's difficult to use bitfields structures to define "templates" for real world
data formats as they now stand.
		
3.  bitfield comparisons

	I guess this is related to point 1 above, but I'd like to be able to
use bitfield structures in comparisons, such as

	if (ma.header == mb.header) ..

I've used unions of ints and bitfield structures to get around this, but
that's a fairly gross hack just to get around a syntactic restriction.



I'd appreciate hearing what people have to say about these ideas.  Are they
stupid, strange, unimplementable or what?

	Andrew

gwyn@brl-smoke.ARPA (Doug Gwyn ) (10/15/87)

In article <112@teletron.UUCP> andrew@teletron.UUCP (Andrew Scott) writes:
>1. structure equality/inequality operators

This has been brought before X3J11 and rejected.  There are several
counterarguments of varying force:
	a. What if the struct contains an array?
		Equality comparison could be extended to aggregates.
	b. What if the struct contains a union?
		The could be made undefined, if we knew how to word it.
	c. Cannot in general use bytewise block comparison (memcmp):
		i. padding may contain garbage
		ii. floating-point representation may not be unique
	d. Simple-looking operation would lead to lots of code, because
		in general the comparison would be done member-by-member.
	e. Facility of limited utility; for instance, a struct member
		is often a pointer to a string, and strcmp() should be
		done on those members, but that is not something the
		compiler is able to determine.
	f. Doesn't help in comparison of "cookies" such as returned by
		fgetpos(), because there's no guarantee that distinct
		cookie encodings will always represent distinct values.
		Such usages should be done via explicit cookiecmp()
		functions.

>2. appropriate bitfield sizing

X3J11 discussed a similar request and decided against it.  I don't have
a record of the reason, but I suspect not a strong enough case was made
for adding this to justify the increased implementation cost.

>It's difficult to use bitfields structures to define "templates" for real world
>data formats as they now stand.

It's difficult in any case!  For example, how to you handle 8-bit byte
oriented data received on a 9-bit byte system?  Bit-fields have limited
utility; they were never intended to be a universal solution to the
problem of externally-imposed data formats.

P.S.  This is not an official X3J11 response.  If you want X3J11 to pay
attention to your ideas, send them to the committee; posting them to
this newsgroup does not guarantee they'll receive a fair hearing.

henry@utzoo.UUCP (Henry Spencer) (10/16/87)

[Disclaimer:  I have no official affiliation with X3J11 and do not speak
for them, although I'm moderately familiar with their work.]

> 	I'd like to see the == and != operators apply to structure variables.
> If structure assignments are allowed (as they are in many compilers), why not
> allow (in)equality operators also?

That issue has come up repeatedly, and so far has been consistently voted
down.  The problem is that you can't just do a byte-by-byte comparison,
because there may be "holes" in structures due to alignment requirements.
There is no guarantee at all about the contents of those holes.  This
doesn't matter for assignment and related operations, but is a non-trivial
problem for comparisons.  There also might be a problem with multiple
representations of the same value, e.g. on a one's-complement machine
there is a separate -0 value that ought to compare equal to +0.  So the
operation ends up being done component-by-component anyway.  Being able
to ask for it without having to write out all the gory details does have
certain advantages, but so far they haven't been compelling enough to get
it accepted, and it's a bit late now.

> 	It would be convenient if one could specify how much space a bitfield
> structure was stored in (instead of always defaulting to int)...

In fact it doesn't default to int; the size of the "unit" of storage in
which bitfields reside is left up to the implementor.  It might be nice
to be able to specify (by request, not implicitly) the size of the storage
wanted, but it's somewhat of a frill.  Many people (including, as I recall,
Dennis Ritchie) have a low opinion of bitfields and think that elaborating
further on them is a waste of effort.

> It's difficult to use bitfields structures to define "templates" for real
> world data formats as they now stand.

In fact it's impossible to do it portably, since there are too many things
left unspecified, like the order of bitfields in a "unit", the policy about
spanning unit boundaries, the size of a unit, etc.  In fact you run into
many of the same problems just using structs *without* bitfields!  With the
language as it stands, this just isn't a wise approach.
-- 
"Mir" means "peace", as in           |  Henry Spencer @ U of Toronto Zoology
"the war is over; we've won".        | {allegra,ihnp4,decvax,utai}!utzoo!henry

jagardner@orchid.UUCP (10/17/87)

re structure comparison in C:

What do you do with unions?
Otherwise, you could use memcmp().

David Tanguay

gwyn@brl-smoke.ARPA (Doug Gwyn ) (10/19/87)

In article <11225@orchid.waterloo.edu> datanguay@watbun.waterloo.edu (David Tanguay) writes:
>What do you do with unions?
>Otherwise, you could use memcmp().

No, except for a few fortunate implementations.  Structs may contain
"holes" with indeterminate contents.  Serial byte-wise comparison
does not work right for most floating-point formats nor for integers
on a little-endian architecture.

jgh@root.co.uk (Jeremy G Harris) (10/22/87)

While we're on the subject, how about a ->= operator (in the tradition
of += etc.)?  I'm continually running down linked lists ;-)

jeremy
-- 
Jeremy Harris			jgh@root.co.uk

mccaugh@uiucdcsb.UUCP (10/28/87)

 This may not be possible. -> is the "indirect component selector" (recall '.'
 is the "direct" one) and according to Harbison & Steele, page 149: "The value
 (of an indirect component selection expression) is the named member of the
 union or structure and (so) is an LVALUE." But on page 184 appears the warn-
 ing that "the result of an assignment expression is NEVER an lvalue." (See
 also page 186.) We are speaking here of "compound" assignment expressions.
 Thus p -> n  must be an lvalue ("namely", n) while p ->= n cannot be. Again,
 if this is confusing, please read page 186 of H&S which admonishes that the
 resulting value stored in the left operand of a compound assignment (such as 
 p -> n in p ->= n) can NOT be an lvalue, which p -> n itself definitely is.

 mccaugh @ uiucmsl

chris@mimsy.UUCP (10/28/87)

In article <165600018@uiucdcsb> mccaugh@uiucdcsb.cs.uiuc.edu writes,
in reply to the idea that since

	a += n;

means, effectively,

	a = a + n;

that

	p ->= member;

ought (effectively) to mean

	p = p -> member;

>... according to Harbison & Steele, page 149: "The value (of an
>indirect component selection expression) is the named member of the
>union or structure and (so) is an LVALUE." But on page 184 appears
>the warning that "the result of an assignment expression is NEVER
>an lvalue." ... Thus p -> n  must be an lvalue ("namely", n) while
>p ->= n cannot be.

True, but irrelevant.  The result of `a += n' is also not an lvalue.
The only relevance that `lvalue-ness' has with op= operators is that
the left hand side of the op= operator must be an lvalue.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris