[comp.lang.c] swaps with arrays

dant@tekla.UUCP (09/08/87)

In article <109@umigw.MIAMI.EDU> steve@umigw.UUCP (steve emmerson) writes:
>
>[swap macro] also won't work with pure array objects (i.e. swapping one
>array with another).  A generic routine should be able to work with
>*anything*.

Can someone tell me why every one expects (or requires) a swap macro to 
work with arrays?  The reason that they don't is that an array name is
a constant and not an object.  For the same reason comparisons of arrays
don't work, you just compare the addresses of the arrays.  So I don't
see why everyone wants the *perfect* swap macro to work for arrays.

A more or less unrelated question:  When they made structure assignments
legal, did they also make structure comparisons legal?

---
Dan Tilque
dant@tekla.tek.com  or dant@tekla.UUCP

steve@umigw.MIAMI.EDU (steve emmerson) (09/08/87)

In article <1354@dataio.Data-IO.COM> bright@dataio.Data-IO.COM (Walter
Bright) wrote:
+--------
| Having a typeof would make creation of 'generic' routines possible:
|	#define swap(a,b)	{ typeof(a) tmp; tmp = a; a = b; b = tmp; }
+--------

To which I responded in article "<109@umigw.MIAMI.EDU> steve@umigw.UUCP"
saying:
+--------
|[swap macro] also won't work with pure array objects (i.e. swapping one
|array with another).  A generic routine should be able to work with
|*anything*.
+--------

Causing Dan Tilque to wonder [bear with me ;-)] (in article
<2376@zeus.TEK.COM> dant@tekla.UUCP):
+--------
|Can someone tell me why every one expects (or requires) a swap macro to 
|work with arrays?  The reason that they don't is that an array name is
|a constant and not an object.  ...
+--------

Well, I can't speak for everyone ;-), but if I was given a generic swap
routine that only worked on a subset of all possible data types ...
well, I might consider it very useful, but I wouldn't consider it
generic.  Someone please correct me if I'm wrong, but I believe a
"generic" routine is one that will work for any type of input (with a
caveat for the above example that the two arguments have the same
type).  Now, in the original article, Walter Bright had the word
"generic" in quotes.  Perhaps he was thinking along these lines and
ment to imply a "pseudo" or "quasi" generic routine (Walter?).

It might be best to chock the whole thing up to "zealous semantic
defense".  If the meaning of the word "generic" gets degraded, then
what word will we use?
-- 
-----------------------------------------------------------------------------
Steve Emmerson                     DDN: emmerson@miami.miami.edu
SPAN: miami::emmerson (host 3.2)        emmerson%miami.span@star.stanford.edu
UUCP: ...!hao!umigw!miami!emmerson      emmerson%miami.span@vlsi.jpl.nasa.gov

quiroz@cs.rochester.edu (Cesar Quiroz) (09/08/87)

Summary:

Expires:

Sender:

Followup-To:



From article <110@umigw.MIAMI.EDU> (steve@umigw.UUCP (steve emmerson)):
:In article <1354@dataio.Data-IO.COM> bright@dataio.Data-IO.COM (Walter
:Bright) wrote:
 -- classic stuff about generic swaps edited out --
:
:Causing Dan Tilque to wonder [bear with me ;-)] (in article
:<2376@zeus.TEK.COM> dant@tekla.UUCP):
:+--------
:|Can someone tell me why every one expects (or requires) a swap macro to 
:|work with arrays?  The reason that they don't is that an array name is
:|a constant and not an object.  ...
:+--------
:
:Well, I can't speak for everyone ;-), but if I was given a generic swap
:routine that only worked on a subset of all possible data types ...
:well, I might consider it very useful, but I wouldn't consider it
:generic.  

What does it have to do with genericity (generic-hood?)?  Dan
Tilque's comment can be seen better in the light of another example:
what would you like
                            swap(1, 2);
to mean?  It seems to me that he has a clear point: C arrays are
constants, `swap' should act on (the values of) variables.

-- 
Cesar Augusto  Quiroz Gonzalez
Department of Computer Science     {allegra|seismo}!rochester!quiroz
University of Rochester            or
Rochester,  NY 14627               quiroz@cs.rochester.edu

steve@umigw.MIAMI.EDU (steve emmerson) (09/09/87)

In article <1955@sol.ARPA> quiroz@ROCHESTER.UUCP (Cesar Quiroz) writes:
+--------
|what would you like
|                            swap(1, 2);
|to mean?
+--------

I think I'm begining to see what you mean: in C, an array is not
*completely* equivalent to a pointer to its first element because its
value may not be altered.  It is therefore meaningless (i.e. semantic
nonsense) to even *consider* using arrays as arguments to a generic
swap routine since they're constants.  One should pass to a swap
routine only "swappable" objects.

Is this correct?

Although I can see the validity of this argument (and I hope I've
restated it correctly) I would argue that the swapping of arrays does
have valid meaning -- namely an element-by-element exchange of values.
This causes each array to become the other and, to me at least, is a
straightforward consequence of swap semantics.  As such, this
functionality should be included in any generic swap routine.

It appears we may differ in our judgement of swap semantics.

What says the rest of the net?
-- 
Steve Emmerson                     DDN: emmerson@miami.miami.edu
SPAN: miami::emmerson (host 3.2)        emmerson%miami.span@star.stanford.edu
UUCP: ...!hao!umigw!miami!emmerson      emmerson%miami.span@vlsi.jpl.nasa.gov

barmar@think.COM (Barry Margolin) (09/10/87)

In article <110@umigw.MIAMI.EDU> steve@umigw.UUCP (steve emmerson) writes:
>Well, I can't speak for everyone ;-), but if I was given a generic swap
>routine that only worked on a subset of all possible data types ...
>well, I might consider it very useful, but I wouldn't consider it
>generic.  Someone please correct me if I'm wrong, but I believe a
>"generic" routine is one that will work for any type of input (with a
>caveat for the above example that the two arguments have the same
>type).  Now, in the original article, Walter Bright had the word
>"generic" in quotes.  Perhaps he was thinking along these lines and
>ment to imply a "pseudo" or "quasi" generic routine (Walter?).

Several people have mentioned that the answer is that array names are
constants.  My point of view on this subject, and I think it directly
addresses the point quoted above, is that the "genericity" of the swap
macro is consistent with the rest of the language.  In C assignment is
generic, but you cannot use an array name as the target of an
assignment.  I don't know why anyone would expect anything in C to
automatically operate element-wise on an array, as it happens in no
other situation.  I'm not an experienced C programmer (although I know
it well enough that I knew why 'if *buffer == *"LDA"' was wrong in the
recent query), but I would expect such people to be SURPRISED when
things automatically handle arrays!

---
Barry Margolin
Thinking Machines Corp.

barmar@think.com
seismo!think!barmar

bright@dataio.Data-IO.COM (Walter Bright) (09/10/87)

In article <110@umigw.MIAMI.EDU> steve@umigw.UUCP (steve emmerson) writes:
>In article <1354@dataio.Data-IO.COM> bright@dataio.Data-IO.COM (Walter
>Bright) wrote:
>| Having a typeof would make creation of 'generic' routines possible:
>|	#define swap(a,b)	{ typeof(a) tmp; tmp = a; a = b; b = tmp; }
>
>To which I responded in article "<109@umigw.MIAMI.EDU> steve@umigw.UUCP"
>saying:
>+--------
>|[swap macro] also won't work with pure array objects (i.e. swapping one
>|array with another).  A generic routine should be able to work with
>|*anything*.
>+--------
>
>Well, I can't speak for everyone ;-), but if I was given a generic swap
>routine that only worked on a subset of all possible data types ...
>well, I might consider it very useful, but I wouldn't consider it
>generic.  Someone please correct me if I'm wrong, but I believe a
>"generic" routine is one that will work for any type of input (with a
>caveat for the above example that the two arguments have the same
>type).  Now, in the original article, Walter Bright had the word
>"generic" in quotes.  Perhaps he was thinking along these lines and
>ment to imply a "pseudo" or "quasi" generic routine (Walter?).

I did mean generic. I know that the above won't work with arrays. But
then, all battle-scarred C programmers know that how arrays work is
botched in C, they just don't work like other types:

	int a[5],b[5];

	a = b;			/* copy contents of b to a	*/
	if (a == b)		/* if contents match		*/
		...
	func(a);		/* push entire array on stack	*/

Of course, none of the above works as 'expected'. This also means that
the usefulness of typedef's is compromised, you still have to be
cognizant if your typedef is an array or a struct or a basic type.

The symmetry and beauty of a language is inversely proportional to the
number of
	if (special case)
		then kludge;
constructs in the parser. A quick look at my compiler (Datalight) sources
confirms that C is jammed with ifs!

Don't get me wrong, C is my language of choice for most of my programs.
But it does have its flaws...

franka@mmintl.UUCP (Frank Adams) (09/11/87)

In article <111@umigw.MIAMI.EDU> steve@umigw.UUCP (steve emmerson) writes:
>Although I can see the validity of this argument (and I hope I've
>restated it correctly) I would argue that the swapping of arrays does
>have valid meaning -- namely an element-by-element exchange of values.
>This causes each array to become the other and, to me at least, is a
>straightforward consequence of swap semantics.  As such, this
>functionality should be included in any generic swap routine.

The point is that a generic facility should work for all objects in some
category.  The appropriate category for a swap macro is that of *assignable*
objects in the language.  And in C, as the result of a series of decisions
which seemed like good ideas at the time, arrays are not assignable.

It is true that the semantics of the assignment of arrays is obvious and
straightforward (I think -- there may be some traps hiding there somewhere).
This is beside the point.  The point is that C doesn't support it.
-- 

Frank Adams                           ihnp4!philabs!pwa-b!mmintl!franka
Ashton-Tate          52 Oakland Ave North         E. Hartford, CT 06108

peter@sugar.UUCP (Peter da Silva) (09/12/87)

There are a lot of things in 'C' that have "meaningful semantics" but are
not supported. Don't hold your breath for:

	Arithmetic on arrays (arithmetic on the elements?).

	Constant arrays other than char: (int *){1, 2, 3} should be
	valid in any context "hi there" is.

	Value return from any block: A = { .... return b; ... return c; }

Can you say "BCPL"? I knew you could.
-- 
-- Peter da Silva `-_-' ...!seismo!soma!uhnix1!sugar!peter
--                 'U`  <-- Public domain wolf.

steve@umigw.MIAMI.EDU (steve emmerson) (09/14/87)

Let me try to summarize what I think I've learned:

    1) There is some miscommunication going on because some of us are 
       talking about generic *routines* while others are talking about 
       generic *macros*. (I'm guilty of thinking about the former while 
       listening about the latter -- sigh).

    2) In the case of a generic macro, I now agree that the semantics of
       a macro must necessarily be constrained by the language in which
       it is written (which should be obvious) and, therefore, it is 
       unrealistic to ask a generic macro to to something which the language
       does not allow (e.g., using array arguments in a swap macro).  When
       writing generic *macros*, it is ligitimate to expect the user to 
       understand the limitations of the language.  Thus, un-&-able or
       unmodifiable swap arguments are an obvious no-no.  The pitfall here
       is *remembering* that that undistinguished, lower-case routine is 
       actually a macro.

    3) In the case of a generic *routine*, I believe there is no reason to 
       assume that its semantics would necessarily be contrained by the
       language of the *calling* routine (forgive me Walter, I misunderstood
       your original posting -- I thought you were talking about this).
       C programs are full of I/O routines, about whose semantics C
       knows nothing.  Also, it is possible (on some machines) to 
       write a routine in a totally separate language and have it do things 
       C can only dream about (to wax poetic for a second).  I still believe
       generic *routines* are instatiations of abstract algorithms and are 
       (or at least should be) unconstrained.

    4) This whole issue has become *almost* moot (register variables, 
       `consts', bitfields, etc -- sigh) since David Goodenough <343@wrs.UUCP>
       posted his macro/sub-routine hybrid which allows the use of array 
       arguments without the need for an explicit length argument.

Gosh this was (continues to be?) fun!
-- 
Steve Emmerson                     DDN: emmerson@miami.miami.edu
SPAN: miami::emmerson (host 3.2)        emmerson%miami.span@star.stanford.edu
UUCP: ...!hao!umigw!miami!emmerson      emmerson%miami.span@vlsi.jpl.nasa.gov

peter@sugar.UUCP (09/16/87)

> It is true that the semantics of the assignment of arrays is obvious and
> straightforward (I think -- there may be some traps hiding there somewhere).
> This is beside the point.  The point is that C doesn't support it.

Snap! The size of an array is not always known to the compiler.

For example:

extern char *sys_errlist[];
-- 
-- Peter da Silva `-_-' ...!hoptoad!academ!uhnix1!sugar!peter
--                 'U`      ^^^^^^^^^^^^^^ Not seismo!soma (blush)

firth@sei.cmu.edu (Robert Firth) (09/22/87)

In article <768@sugar.UUCP> peter@sugar.UUCP (Peter da Silva) writes:
>> It is true that the semantics of the assignment of arrays is obvious and
>> straightforward (I think -- there may be some traps hiding there somewhere).

>Snap! The size of an array is not always known to the compiler.
>
>For example:
>
>extern char *sys_errlist[];

But neither is the size of an array in Algol-60, Algol-68, Ada, or most
other languages that support soem form of array assignment.  There would
surely be no difficulty is accessing a runtime descriptor that gave the
array size?

In fact, since in C all declared arrays have a static size, one could
simply generate a hidden external name "sys_errlist_size" or whatever,
resolved at link time, and use that.  No harder than resolving the
array name at link time.  On a Vax-11, for instance,

	.GLOBAL sys_errlist_size, sys_errlist
	MOVC3 #sys_errlist_size, G^sys_errlist, copy_of_sys_errlist

would do the job.