The Unix Heritage Society mailing list
 help / color / mirror / Atom feed
* [TUHS] C declarations.
@ 2017-05-11 21:49 Ron Natalie
  2017-05-11 22:01 ` Arthur Krewat
  2017-05-11 22:03 ` David Arnold
  0 siblings, 2 replies; 48+ messages in thread
From: Ron Natalie @ 2017-05-11 21:49 UTC (permalink / raw)


Bjarne agrees with you.   He put the * (and the &) with the type name to emphasize it is part of the type.
This works fine as long as you only use one declaration per statement.

The problem with that is that * doesn't really bind to the type name.   It binds to the variable.

char* cp1, cp2;   // cp1 is pointer to char,   cp2 is just a char.

I always found it confusing that the * is used to indicate an pointer here, where as when you want to change an lvalue to a pointer, you use &.

But if we're going to gripe about the evolution of C.   My biggest gripe is when they fixed structs to be real types, they didn't also do so for arrays.
Arrays and their  degeneration to poitners is one of the biggest annoyances in C.

> Am I the only one here who thinks that e.g. a char pointer should be
> "char* cp1, cp2" instead of "char *cp1, *cp2"?  I.e. the fundamental type is "char*", not "char", and to this day I still write:




^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-11 21:49 [TUHS] C declarations Ron Natalie
@ 2017-05-11 22:01 ` Arthur Krewat
  2017-05-11 23:44   ` Dave Horsfall
  2017-05-11 22:03 ` David Arnold
  1 sibling, 1 reply; 48+ messages in thread
From: Arthur Krewat @ 2017-05-11 22:01 UTC (permalink / raw)



But wouldn't that imply you didn't need to use the * when referencing 
the actual value?

For example, if you do this:

char *p;
char c;

The correct way to get the character it's pointing to dereference like this:

c=*p;

If the type was char* (not char)

Wouldn't that imply I wouldn't need the * to dereference the pointer?




On 5/11/2017 5:49 PM, Ron Natalie wrote:
> Bjarne agrees with you.   He put the * (and the &) with the type name to emphasize it is part of the type.
> This works fine as long as you only use one declaration per statement.
>
> The problem with that is that * doesn't really bind to the type name.   It binds to the variable.
>
> char* cp1, cp2;   // cp1 is pointer to char,   cp2 is just a char.
>
> I always found it confusing that the * is used to indicate an pointer here, where as when you want to change an lvalue to a pointer, you use &.
>
> But if we're going to gripe about the evolution of C.   My biggest gripe is when they fixed structs to be real types, they didn't also do so for arrays.
> Arrays and their  degeneration to poitners is one of the biggest annoyances in C.
>
>> Am I the only one here who thinks that e.g. a char pointer should be
>> "char* cp1, cp2" instead of "char *cp1, *cp2"?  I.e. the fundamental type is "char*", not "char", and to this day I still write:
>
>
>



^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-11 21:49 [TUHS] C declarations Ron Natalie
  2017-05-11 22:01 ` Arthur Krewat
@ 2017-05-11 22:03 ` David Arnold
  2017-05-11 22:32   ` Larry McVoy
  1 sibling, 1 reply; 48+ messages in thread
From: David Arnold @ 2017-05-11 22:03 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 385 bytes --]

> On 12 May 2017, at 07:49, Ron Natalie <ron at ronnatalie.com> wrote:
> 
> <…>
> But if we're going to gripe about the evolution of C.   My biggest gripe is when they fixed structs to be real types, they didn't also do so for arrays.
> Arrays and their  degeneration to poitners is one of the biggest annoyances in C.

And, conversely (perversely?) one of its greatest joys.



d



^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-11 22:03 ` David Arnold
@ 2017-05-11 22:32   ` Larry McVoy
  2017-05-11 22:41     ` Ron Natalie
  2017-05-12  0:15     ` Bakul Shah
  0 siblings, 2 replies; 48+ messages in thread
From: Larry McVoy @ 2017-05-11 22:32 UTC (permalink / raw)


On Fri, May 12, 2017 at 08:03:28AM +1000, David Arnold wrote:
> > On 12 May 2017, at 07:49, Ron Natalie <ron at ronnatalie.com> wrote:
> > 
> > <???>
> > But if we're going to gripe about the evolution of C.   My biggest gripe is when they fixed structs to be real types, they didn't also do so for arrays.
> > Arrays and their  degeneration to poitners is one of the biggest annoyances in C.
> 
> And, conversely (perversely?) one of its greatest joys.

I dunno if it is one of its greatest joys but pointers in C have always 
made sense to me.

I'm curious as to what is busted about arrays in C?  To me they just
seemed like a way to define how to look at a wad of memory and they
seem to work for me.  About the only thing I don't like about them is
that there is no late binding as to the size, Ada has late binding and
I thought it could be useful (I only know because Rob Netzer and I 
wrote an Ada compiler for CS736 at UW-Madison that did a lot of Ada
but exceptions and late binding we did not do).

--lm


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-11 22:32   ` Larry McVoy
@ 2017-05-11 22:41     ` Ron Natalie
  2017-05-13  1:24       ` Larry McVoy
  2017-05-12  0:15     ` Bakul Shah
  1 sibling, 1 reply; 48+ messages in thread
From: Ron Natalie @ 2017-05-11 22:41 UTC (permalink / raw)



>  I'm curious as to what is busted about arrays in C?  To me they just
seemed like a way to define how to look at a wad of memory and they seem to
work for me.  

The problem is they don't work like every other type.    Somewhere around
the phototypesetter release or V7, they fixed structs to be
assignable/passable to functions.
They didn't do that for arrays.   They retained their half-assed
quasipointer status.    It would have been easy to bite the bullet back in
those days before people codified the inane behavior.

For example:

struct foo {
    int a;
    int b;
};

struct foo x;
x.a = 1;
x.b = 1;
struct foo y;
y = x; // works fine.

struct foo myfunc(struct foo arg) {
    arg.a = 5;
    return 5;
}
y = myfunc(x);   // does not modify x


Now look at arrays:

char x[4] = { 1, 2, 3, 4};

char y[4];
y = x ; // illegal

void myfunc(char arg[4]) {
    arg[0] = 1000;
}

myfunc(x);  // CHANGES X!

If had my way, y = x and passing and returning arrays by value would work
just like every other C type.




^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-11 22:01 ` Arthur Krewat
@ 2017-05-11 23:44   ` Dave Horsfall
  0 siblings, 0 replies; 48+ messages in thread
From: Dave Horsfall @ 2017-05-11 23:44 UTC (permalink / raw)


On Thu, 11 May 2017, Arthur Krewat wrote:

> But wouldn't that imply you didn't need to use the * when referencing 
> the actual value?
> 
> For example, if you do this:
> 
> char *p;
> char c;
> 
> The correct way to get the character it's pointing to dereference like 
> this:
> 
> c=*p;
> 
> If the type was char* (not char)
> 
> Wouldn't that imply I wouldn't need the * to dereference the pointer?

No, because you'd be assigning the contents i.e. the address (or however 
references are implemented on a given architecture) to a character; 
whether the fundamental type is "char*" or ("mostly char but it's really a 
pointer") is the same.

Then again, I learned ALGOLW (and PASCAL) before I learned C, and it has a 
"REFERENCE" type...

-- 
Dave Horsfall DTM (VK2KFU)  "Those who don't understand security will suffer."


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-11 22:32   ` Larry McVoy
  2017-05-11 22:41     ` Ron Natalie
@ 2017-05-12  0:15     ` Bakul Shah
  2017-05-12  2:41       ` Theo Pavlidis
  1 sibling, 1 reply; 48+ messages in thread
From: Bakul Shah @ 2017-05-12  0:15 UTC (permalink / raw)


On Thu, 11 May 2017 15:32:32 PDT Larry McVoy <lm at mcvoy.com> wrote:
> 
> I dunno if it is one of its greatest joys but pointers in C have always 
> made sense to me.
> 
> I'm curious as to what is busted about arrays in C?  To me they just
> seemed like a way to define how to look at a wad of memory and they
> seem to work for me.  About the only thing I don't like about them is
> that there is no late binding as to the size, Ada has late binding and
> I thought it could be useful (I only know because Rob Netzer and I 
> wrote an Ada compiler for CS736 at UW-Madison that did a lot of Ada
> but exceptions and late binding we did not do).

Coming from a Pascal background I really liked the terseness
of C. But theere were three things that bothered me.

a) K&R style argument declarations. This got fixed in ANSI C.
   C declarations were messy but that did not bother me much.

b) No nested procedures. Gnu C had added them but the
   implementation was a bit screwy and most people didn't care
   in any case so there was no hope of this getting fixed.
   Partly because most people used it as a portable assembly
   language!

c) arrays were not first class objects.  Given "T v[N];" v[i]
   is of type T and i+v or v+i is of type T* -- this is
   perfectly well defined and fine. What is not fine is that
   an array is a second class object. Thus you can not do
   for example,

    int v[5];
    struct foo {
	int w[5];
	int x;
    } y;
	...
	y.w = v;

   You can not pass a whole array to a function (or return
   one) without enclosing it in a struct. You can not take an
   address of an array, only an element of it. There is no way
   to declare or pass a subarray. A function that operates on a
   arbitray sized  multi dim. array can be written but can get
   messy.

   One big impact of current array behavior is that the onus
   to do boundary condition checks is on the programmer and
   can't be done by the compiler.

Just as Pascal got "conformant arrays" in its 1990 standard,
arrays could've been made first class (but without "ref"
parameters code can look messy). For instance, consider the
folloowing:

    double a[5,20], b[20,10], c[5,10];
    int err = mat_multiply(c, a, b);

    int mat_mult(ref double c[int cx, cy], a[int ax, ay], b[int bx, by]) {
	if (cx != ax || cy != by || ay != bx) return -1;
	...
	return 0;
    }

This can be implemented without much trouble and allows
full boundary condition checking.  Currently the user will
have to manually pass {a,b,c}{x,y} parameters and he would
have to either create auxiliary vectors to point to each row
or have the function to do all the index arithmetic explicitly
(and the compiler can't check if your code has no boundary
condition bugs).

A slightly more difficult situation arises when you want to
pass sub arrays. For instance,

	mat_mutl(c[5,0:9], a[5,10:19], b[0:9,0:5])

Here you will have to somehow pass stride and offset (or use
iliffe vectors or some such).


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-12  0:15     ` Bakul Shah
@ 2017-05-12  2:41       ` Theo Pavlidis
  0 siblings, 0 replies; 48+ messages in thread
From: Theo Pavlidis @ 2017-05-12  2:41 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 3786 bytes --]

I tend to stay away from using arrays as arguments of procedures, too many
surprises. Instead I use structures.
For example:

typedef struct {
.........
xteam NoSo[MAXB], EsWe[MAXB];
} xboard;
............
xboard TB;
............
       ScoreBoard(..., &TB, ...);


Of course, in my old age I only do simple game programming
​


Theo Pavlidis
(
​Member of 1127: 1980-86)
​
On Thu, May 11, 2017 at 8:15 PM, Bakul Shah <bakul at bitblocks.com> wrote:

> On Thu, 11 May 2017 15:32:32 PDT Larry McVoy <lm at mcvoy.com> wrote:
> >
> > I dunno if it is one of its greatest joys but pointers in C have always
> > made sense to me.
> >
> > I'm curious as to what is busted about arrays in C?  To me they just
> > seemed like a way to define how to look at a wad of memory and they
> > seem to work for me.  About the only thing I don't like about them is
> > that there is no late binding as to the size, Ada has late binding and
> > I thought it could be useful (I only know because Rob Netzer and I
> > wrote an Ada compiler for CS736 at UW-Madison that did a lot of Ada
> > but exceptions and late binding we did not do).
>
> Coming from a Pascal background I really liked the terseness
> of C. But theere were three things that bothered me.
>
> a) K&R style argument declarations. This got fixed in ANSI C.
>    C declarations were messy but that did not bother me much.
>
> b) No nested procedures. Gnu C had added them but the
>    implementation was a bit screwy and most people didn't care
>    in any case so there was no hope of this getting fixed.
>    Partly because most people used it as a portable assembly
>    language!
>
> c) arrays were not first class objects.  Given "T v[N];" v[i]
>    is of type T and i+v or v+i is of type T* -- this is
>    perfectly well defined and fine. What is not fine is that
>    an array is a second class object. Thus you can not do
>    for example,
>
>     int v[5];
>     struct foo {
>         int w[5];
>         int x;
>     } y;
>         ...
>         y.w = v;
>
>    You can not pass a whole array to a function (or return
>    one) without enclosing it in a struct. You can not take an
>    address of an array, only an element of it. There is no way
>    to declare or pass a subarray. A function that operates on a
>    arbitray sized  multi dim. array can be written but can get
>    messy.
>
>    One big impact of current array behavior is that the onus
>    to do boundary condition checks is on the programmer and
>    can't be done by the compiler.
>
> Just as Pascal got "conformant arrays" in its 1990 standard,
> arrays could've been made first class (but without "ref"
> parameters code can look messy). For instance, consider the
> folloowing:
>
>     double a[5,20], b[20,10], c[5,10];
>     int err = mat_multiply(c, a, b);
>
>     int mat_mult(ref double c[int cx, cy], a[int ax, ay], b[int bx, by]) {
>         if (cx != ax || cy != by || ay != bx) return -1;
>         ...
>         return 0;
>     }
>
> This can be implemented without much trouble and allows
> full boundary condition checking.  Currently the user will
> have to manually pass {a,b,c}{x,y} parameters and he would
> have to either create auxiliary vectors to point to each row
> or have the function to do all the index arithmetic explicitly
> (and the compiler can't check if your code has no boundary
> condition bugs).
>
> A slightly more difficult situation arises when you want to
> pass sub arrays. For instance,
>
>         mat_mutl(c[5,0:9], a[5,10:19], b[0:9,0:5])
>
> Here you will have to somehow pass stride and offset (or use
> iliffe vectors or some such).
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://minnie.tuhs.org/pipermail/tuhs/attachments/20170511/0b5b8993/attachment.html>


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-11 22:41     ` Ron Natalie
@ 2017-05-13  1:24       ` Larry McVoy
  2017-05-13  2:45         ` Ron Natalie
  0 siblings, 1 reply; 48+ messages in thread
From: Larry McVoy @ 2017-05-13  1:24 UTC (permalink / raw)


On Thu, May 11, 2017 at 06:41:47PM -0400, Ron Natalie wrote:
> If had my way, y = x and passing and returning arrays by value would work
> just like every other C type.

Maybe, just maybe, now that makes sense.  But even now that would be a 
perf hit unless you added some magical copy on write semantics like 
Tcl has so it can have pass by value semantics but pass by reference
performance.

Back then, I think the perf hit would have been so bad everyone would be
passing arrays as a reference anyway.
-- 
---
Larry McVoy            	     lm at mcvoy.com             http://www.mcvoy.com/lm 


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-13  1:24       ` Larry McVoy
@ 2017-05-13  2:45         ` Ron Natalie
  2017-05-13 12:20           ` Michael Kjörling
  0 siblings, 1 reply; 48+ messages in thread
From: Ron Natalie @ 2017-05-13  2:45 UTC (permalink / raw)


There's no performance "hit" because it doesn't work now.    There's really
no difference performance or computational complexity wise for

char x[4], y[4];
x = y;
and
struct { char a[4]; } x, y;
x = y;

About the only thing it would have broken (and would still break today), is
the fact that function parameters that are defined to be arrays, really pass
pointers.

char x[4];
void foo(char a[4]);
foo(x);

would be costlier than it is now doing the pass by value.    Of course you
could always fudge if you wanted to pass the pointer by actually doing it
that way...
char x[4]
void foo(char *a);
foo(x);

-----Original Message-----
From: Larry McVoy [mailto:lm@mcvoy.com] 
Sent: Friday, May 12, 2017 9:24 PM
To: Ron Natalie
Cc: 'Larry McVoy'; 'David Arnold'; 'The Eunuchs Hysterical Society'
Subject: Re: [TUHS] C declarations.

On Thu, May 11, 2017 at 06:41:47PM -0400, Ron Natalie wrote:
> If had my way, y = x and passing and returning arrays by value would 
> work just like every other C type.

Maybe, just maybe, now that makes sense.  But even now that would be a perf
hit unless you added some magical copy on write semantics like Tcl has so it
can have pass by value semantics but pass by reference performance.

Back then, I think the perf hit would have been so bad everyone would be
passing arrays as a reference anyway.
--
---
Larry McVoy            	     lm at mcvoy.com
http://www.mcvoy.com/lm 



^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-13  2:45         ` Ron Natalie
@ 2017-05-13 12:20           ` Michael Kjörling
  2017-05-13 12:35             ` Tim Bradshaw
  2017-05-13 19:05             ` Random832
  0 siblings, 2 replies; 48+ messages in thread
From: Michael Kjörling @ 2017-05-13 12:20 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 3931 bytes --]

On 12 May 2017 22:45 -0400, from ron at ronnatalie.com (Ron Natalie):
> About the only thing it would have broken (and would still break today), is
> the fact that function parameters that are defined to be arrays, really pass
> pointers.
> 
> char x[4];
> void foo(char a[4]);
> foo(x);
> 
> would be costlier than it is now doing the pass by value.

Correct me if I am wrong, but _pass by value_ as opposed to _pass by
reference_ requires making a copy, no? That's the whole point, to
allow the callee to poke at the value it is given at will. At the very
least, it would require making a copy when a part of the passed value
is modified. Where is that memory going to come from, when even
malloc() isn't a part of the language but rather a part of the
standard library? Where is all that going to come from if you pass a
large array on a memory-constrained system of specs common back in the
days when C was designed, especially one that lacks virtual memory
support?

What if (yes, somewhat contrived example) we had pass by value
semantics, and foo() is implemented as

    void foo(char a[4])
    {
        a[8] = 123;
    }

What exactly should happen? The function delcaration says we are
interested in four char, but the function uses far more than that. You
could of course invoke the almighty term _undefined behavior_, but you
really have to say _something_. And of course, nothing stops us from
calling that function as

    char x[100];
    foo(x);

To reliably prevent that, it seems to me you'd need to at least amend
arrays to know their own size, especially if you don't want the
compiler to throw its hands in the air as soon as it sees a malloc()
(and recognizes it).

Now consider instead something like

    struct foo_t { char a[4]; char b[10]; };
    union foo_u { char[14] x; struct foo_t s; };
    void foo(foo_u u)
    {
        u.s.a[8] = 123;
    }

(Please excuse any syntax errors there; unions have never been my
strong side.)

While I agree that _you shouldn't be doing that in the first place_,
the fact remains that doing it is not _disallowed_ by the language. It
could be disallowed by the language if the array knows its size, but
to reliably disallow it, you'd need to be able to detect it at compile
time. That would seem to significantly increase the complexity of the
compiler, which of course we wouldn't want on a low-spec system. (I
have a strong suspicion that my microwave oven has more computing
power and memory than some of the systems C was designed to run on...)


> Of course you
> could always fudge if you wanted to pass the pointer by actually doing it
> that way...
> char x[4]
> void foo(char *a);
> foo(x);

...in which case you need to know from somewhere else whether foo()
wants a zero-terminated char array or not. Not impossible -- we
already have a similar situation with, say, memcmp() and strncmp() --
but unless you're willing to introduce some additional syntax, it
seems to me that you lose expressiveness in the language by lumping
the two cases together.

All the above said, _please don't get me wrong_. Pass by value
semantics is a really nice feature to have, and I have been known to
curse at certain languages more than once where the normal behavior is
pass by reference and pass by value requires a good deal of extra
code. But for potentially large (or even undefined-size) types, pass
by value comes at a significant cost in terms of memory, and even the
copying itself. Copy-on-write solves some of that but requires
elaborate bookkeeping instead, to know what goes where (it's at least
one additional layer of indirection), and risks fragmentation. For
simplicity and predictability, it's hard to beat pass by reference.

-- 
Michael Kjörling • https://michael.kjorling.se • michael at kjorling.se
                 “People who think they know everything really annoy
                 those of us who know we don’t.” (Bjarne Stroustrup)


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-13 12:20           ` Michael Kjörling
@ 2017-05-13 12:35             ` Tim Bradshaw
  2017-05-13 12:42               ` Michael Kjörling
                                 ` (2 more replies)
  2017-05-13 19:05             ` Random832
  1 sibling, 3 replies; 48+ messages in thread
From: Tim Bradshaw @ 2017-05-13 12:35 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1031 bytes --]

On 13 May 2017, at 13:20, Michael Kjörling <michael at kjorling.se> wrote:
> 
> Correct me if I am wrong, but _pass by value_ as opposed to _pass by
> reference_ requires making a copy, no? That's the whole point, to
> allow the callee to poke at the value it is given at will. At the very
> least, it would require making a copy when a part of the passed value
> is modified. Where is that memory going to come from, when even
> malloc() isn't a part of the language but rather a part of the
> standard library? Where is all that going to come from if you pass a
> large array on a memory-constrained system of specs common back in the
> days when C was designed, especially one that lacks virtual memory
> support?

Are there languages that copy arrays in function calls defaultly?  Perhaps Fortran has some convention that allows that but I doubt it gets used very much, because it would be insane in most cases:  COMPUTE_MEAN_TEMPERATURE(ATMOS) is really *not* going to work very well if it involves copying the ATMOS array.


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-13 12:35             ` Tim Bradshaw
@ 2017-05-13 12:42               ` Michael Kjörling
  2017-05-13 15:36                 ` Stephen Kitt
  2017-05-14  1:59                 ` Lawrence Stewart
  2017-05-13 13:46               ` [TUHS] " Hellwig Geisse
  2017-05-13 19:08               ` Random832
  2 siblings, 2 replies; 48+ messages in thread
From: Michael Kjörling @ 2017-05-13 12:42 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 790 bytes --]

On 13 May 2017 13:35 +0100, from tfb at tfeb.org (Tim Bradshaw):
> Are there languages that copy arrays in function calls defaultly?
> Perhaps Fortran has some convention that allows that but I doubt it
> gets used very much, because it would be insane in most cases:
> COMPUTE_MEAN_TEMPERATURE(ATMOS) is really *not* going to work very
> well if it involves copying the ATMOS array.

I'm not completely sure about arrays, but at least Java has pass by
reference in some cases where you might expect pass by value. IIRC
function return values is a prime example.

-- 
Michael Kjörling • https://michael.kjorling.se • michael at kjorling.se
                 “People who think they know everything really annoy
                 those of us who know we don’t.” (Bjarne Stroustrup)


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-13 12:35             ` Tim Bradshaw
  2017-05-13 12:42               ` Michael Kjörling
@ 2017-05-13 13:46               ` Hellwig Geisse
  2017-05-13 19:08               ` Random832
  2 siblings, 0 replies; 48+ messages in thread
From: Hellwig Geisse @ 2017-05-13 13:46 UTC (permalink / raw)


On Sa, 2017-05-13 at 13:35 +0100, Tim Bradshaw wrote:
> Are there languages that copy arrays in
> function calls defaultly?

Yes, Pascal is an example. If you do *not* want
an argument to be copied, its corresponding
parameter name must be preceded by the keyword
"var". The "User Manual and Report" explicitly
warns about the inefficiency incurred when
calling functions with parameters of structured
types (arrays or records) without "var".

Hellwig


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-13 12:42               ` Michael Kjörling
@ 2017-05-13 15:36                 ` Stephen Kitt
  2017-05-14  1:59                 ` Lawrence Stewart
  1 sibling, 0 replies; 48+ messages in thread
From: Stephen Kitt @ 2017-05-13 15:36 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1184 bytes --]

On Sat, 13 May 2017 12:42:47 +0000, Michael Kjörling <michael at kjorling.se>
wrote:
> On 13 May 2017 13:35 +0100, from tfb at tfeb.org (Tim Bradshaw):
> > Are there languages that copy arrays in function calls defaultly?
> > Perhaps Fortran has some convention that allows that but I doubt it
> > gets used very much, because it would be insane in most cases:
> > COMPUTE_MEAN_TEMPERATURE(ATMOS) is really *not* going to work very
> > well if it involves copying the ATMOS array.  
> 
> I'm not completely sure about arrays, but at least Java has pass by
> reference in some cases where you might expect pass by value. IIRC
> function return values is a prime example.

Technically (and this is serious nit-picking), Java is always pass-by-value,
but the value of an array or object *variable* is the reference to the array
or object, not the array or object itself. So the behaviour is
pass-by-reference for arrays and objects (although that’s a simplification
too, and unhelpful in some instances).

The same applies to return values: primitive types are returned by value
(copied), arrays and objects are returned via their reference (which is
copied too).

Regards,

Stephen


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-13 12:20           ` Michael Kjörling
  2017-05-13 12:35             ` Tim Bradshaw
@ 2017-05-13 19:05             ` Random832
  2017-05-14 13:14               ` Derek Fawcus
  1 sibling, 1 reply; 48+ messages in thread
From: Random832 @ 2017-05-13 19:05 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 583 bytes --]

On Sat, May 13, 2017, at 08:20, Michael Kjörling wrote:
> Correct me if I am wrong, but _pass by value_ as opposed to _pass by
> reference_ requires making a copy, no? That's the whole point, to
> allow the callee to poke at the value it is given at will.

If that were the issue, the callee could simply automatically make the
copy if-and-only-if it needs it.

The reason that it can't be done without making a copy is, rather, that
there might be some *other* reference in play, through which the
original array could be modified (thus improperly changing what the
callee sees).


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-13 12:35             ` Tim Bradshaw
  2017-05-13 12:42               ` Michael Kjörling
  2017-05-13 13:46               ` [TUHS] " Hellwig Geisse
@ 2017-05-13 19:08               ` Random832
  2017-05-13 23:21                 ` Dave Horsfall
  2 siblings, 1 reply; 48+ messages in thread
From: Random832 @ 2017-05-13 19:08 UTC (permalink / raw)


On Sat, May 13, 2017, at 08:35, Tim Bradshaw wrote:
> Are there languages that copy arrays in function calls defaultly? 
> Perhaps Fortran has some convention that allows that but I doubt it gets
> used very much, because it would be insane in most cases: 
> COMPUTE_MEAN_TEMPERATURE(ATMOS) is really *not* going to work very well
> if it involves copying the ATMOS array.

Fortran, for the record, passes nearly everything by reference - to call
a fortran function from C (or to make a C function callable from
fortran) you've got to mangle the name and change almost everything to
pointers.


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-13 19:08               ` Random832
@ 2017-05-13 23:21                 ` Dave Horsfall
  2017-05-14 14:48                   ` Nemo
  0 siblings, 1 reply; 48+ messages in thread
From: Dave Horsfall @ 2017-05-13 23:21 UTC (permalink / raw)


On Sat, 13 May 2017, Random832 wrote:

> Fortran, for the record, passes nearly everything by reference [...]

And if you passed a constant and the local argument was modified, so was 
the (single instance of) constant...

Actually, wasn't FORTRAN value-result i.e. all args were copied straight 
back again, or am I confusing that with ALGOL?  Blimey, it's been over 40 
years since I last submitted a card deck.

-- 
Dave Horsfall DTM (VK2KFU)  "Those who don't understand security will suffer."


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-13 12:42               ` Michael Kjörling
  2017-05-13 15:36                 ` Stephen Kitt
@ 2017-05-14  1:59                 ` Lawrence Stewart
  2017-05-14  2:23                   ` Dave Horsfall
  2017-05-14  4:24                   ` Bakul Shah
  1 sibling, 2 replies; 48+ messages in thread
From: Lawrence Stewart @ 2017-05-14  1:59 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1443 bytes --]

I am not troubled at all by C’s conflation of arrays and pointers. That has always seemed natural - it is what is really going on under the covers.*

I’m the sort of person who fiddles with the source code until the compiler generates the code I want.  C is great for this.  Not always, but C compilers usually do the straightforward and obvious thing and generate the code you would write if you had to do it in assembler, only the compiler keeps track of the stupid details like frame offsets and inventing symbol names for branch targets.

I’ve written substantive things in Java, Modula-3, common lisp, python, and so forth, but when I write performance sensitive code, I do it in C**

I tend to work on communications code and when you are counting cycles in some HPC library, you write in C but think of every load, store, and shift.  My affinity for the language began the same way it probably did for a lot of people here: when I realized that *i++ was exactly a PDP11 addressing mode.

When the assistant rector at my church had a meeting about sacred texts, I brought in K&R (“the New Testament” second edition) and my prized copies of the BSTJ Unix issues.

-L

PS  

* - But I have never been able to remember the syntax for function pointers.  I always “man qsort” to refresh my memory.

** - If the code uses multidimensional arrays or subarrays, then maybe FORTRAN, because really x[i*stride+j] gets really old.



^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-14  1:59                 ` Lawrence Stewart
@ 2017-05-14  2:23                   ` Dave Horsfall
  2017-05-14  4:24                   ` Bakul Shah
  1 sibling, 0 replies; 48+ messages in thread
From: Dave Horsfall @ 2017-05-14  2:23 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 430 bytes --]

On Sat, 13 May 2017, Lawrence Stewart wrote:

> * - But I have never been able to remember the syntax for function 
> pointers.  I always “man qsort” to refresh my memory.

"cdecl" is your friend:

    % cdecl
    Type `help' or `?' for help
    declare foo as pointer to function (int, double) returning void
    void (*foo)(int , double )

-- 
Dave Horsfall DTM (VK2KFU)  "Those who don't understand security will suffer."


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-14  1:59                 ` Lawrence Stewart
  2017-05-14  2:23                   ` Dave Horsfall
@ 2017-05-14  4:24                   ` Bakul Shah
  2017-05-14  6:12                     ` Steve Johnson
  2017-05-15  4:35                     ` Dave Horsfall
  1 sibling, 2 replies; 48+ messages in thread
From: Bakul Shah @ 2017-05-14  4:24 UTC (permalink / raw)


On Sat, 13 May 2017 21:59:57 EDT Lawrence Stewart <stewart at serissa.com> wrote:
>
> * - But I have never been able to remember the syntax for function pointers.  > I always "man qsort" to refresh my memory.

The way I remember:

given *x[] or *x(), x /sticks/ to the /right/ first. Thus

int *x[];	// x is array of ptr to int
int *x();	// x is a function returning ptr to int

If you don't want a var to stick to its right, separate using
using parentheses.

int (*x)[];	// x is a ptr to array of ints
int (*x)();	// x is a ptr to function returning int
int *(*x)[];	// x is a ptr to array of ptrs to int

This sort of also works for multiple variables in one declaration. Given

int *x, y;	// * /sticks/ to the right (x) first, so not available for y.

Now if they'd allowed parenthesizing the type, as in

(int *)x, y;

we would see that both x & y are of type int *. That would've also allowed
declaring multiple vars in one declaration where the previous rule applies!

(int*)(*f,*g)();

Part of the confusion is * is tacked on at the front while []
& () at the back of a variable.  Someone (Chandy?) had
proposed unifying this syntax but it didn't go anywhere.  I
think the author used @ in a suffix place though I don't
recall any other details.  But if you put the var all the way
to the right and read a declaration right to left, it works:

int*[] x	// x is a array of ptr to ints
int() f		// f is a function returning it
int*()* f	// f is a ptr to function returning ptr to int
int*()* f,g	// f & g are ptrs to function returning ptr to int

This is only slightly weird if you are used to the current syntax
but you can easily retrain yourself.

IMHO, where evolution of C, Scheme and most programming
languages goes wrong is doing evolutionary design by
committee.  Most users grasp what is easier to use vs what is
hard but they don't have the aesthetic sense or imagination or
training to make things simple. And in large groups popularity
or force of personality or some other irrelevant attribute
wins not aesthetics.  Language evolution IMHO must be done by
benevolent dictatorship or a guild of like minded people who
have worked together for a long time!  Go seems to have
adapted that style....


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-14  4:24                   ` Bakul Shah
@ 2017-05-14  6:12                     ` Steve Johnson
  2017-05-14  6:48                       ` Bakul Shah
  2017-05-15  4:35                     ` Dave Horsfall
  1 sibling, 1 reply; 48+ messages in thread
From: Steve Johnson @ 2017-05-14  6:12 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 5335 bytes --]

I can't resist jumping in here.   My main point is that system coding
is a rather different beast than most application programming.  An
operating system must be able to handle memory allocation requests
from a user without knowing any details of what is requested.  Dennis
explicitly left out a heap and garbage collection code in C because he
didn't want OS code to be burdened with it.  Similarly with a "real"
string type (with concatenation, etc.).

An example that speaks to me is that of creating a symbol table.
 This isn't kernel programming, but consider what is needed:

	* A structure that holds the individual table entries
	* A tree of lookup tables that reflects the scoping rules of the
language -- several tables might need to be searched to find an entry
	* A function that looks up a name in a scope, returns the entry if
it's defined, and adds a new entry in the appropriate scope if it
isn't there yet.

Statistically a majority of the calls do not change the symbol table,
but some do, and you can't tell in advance.  And in the same way,
many of the possible scopes where a variable might reside need not be
searched.

So how much of this table should we copy into the lookup function?
 The answer seems obvious to me -- none of it...

Before Unix, Dennis and I and several other people worked on a
symbolic algebra system written in FORTRAN.  Dennis wrote a dynamic
storage allocator, which was a real feat in FORTRAN, complete with
garbage collector.  The goal was to have the program work on the 6
major manufacturers' FORTRANs.  We got it up and running on many of
the systems, but did not have easy access to OS 360.   Finally, we
were granted the third shift on the OS 360, and ran our program (that
had become rather solid by this time...).   It was a disaster -- the
brogram ran for a few second and then the OS dies and could not be
restarted (turns out the core dump area allotted on the disc was not
big enough to hold our program).  

The problem turned out to be that the IBM compiler did copy in/copy
out argument passing, while all the other compilers passed by
reference.  If you passed in an argument  that was dynamically
allocated, and the system did a garbage collection, all the elements
that were still live were moved around but kept their contents
intact... until the function returned, and tried to copy the changed
value out _where that block used to be at the time of the call._

It took us about 6 months to rewrite the system so we didn't do that
-- we had to allocate everything that would be needed first, then do
the work, and then free things...

None of us were fans of copy in/copy out after that experience...

Steve

----- Original Message -----
From: "Bakul Shah" <bakul@bitblocks.com>
To:"Lawrence Stewart" <stewart at serissa.com>
Cc:"tuhs" <tuhs at minnie.tuhs.org>
Sent:Sat, 13 May 2017 21:24:11 -0700
Subject:Re: [TUHS] C declarations.

 On Sat, 13 May 2017 21:59:57 EDT Lawrence Stewart
<stewart at serissa.com> wrote:
 >
 > * - But I have never been able to remember the syntax for function
pointers. > I always "man qsort" to refresh my memory.

 The way I remember:

 given *x[] or *x(), x /sticks/ to the /right/ first. Thus

 int *x[]; // x is array of ptr to int
 int *x(); // x is a function returning ptr to int

 If you don't want a var to stick to its right, separate using
 using parentheses.

 int (*x)[]; // x is a ptr to array of ints
 int (*x)(); // x is a ptr to function returning int
 int *(*x)[]; // x is a ptr to array of ptrs to int

 This sort of also works for multiple variables in one declaration.
Given

 int *x, y; // * /sticks/ to the right (x) first, so not available for
y.

 Now if they'd allowed parenthesizing the type, as in

 (int *)x, y;

 we would see that both x & y are of type int *. That would've also
allowed
 declaring multiple vars in one declaration where the previous rule
applies!

 (int*)(*f,*g)();

 Part of the confusion is * is tacked on at the front while []
 & () at the back of a variable. Someone (Chandy?) had
 proposed unifying this syntax but it didn't go anywhere. I
 think the author used @ in a suffix place though I don't
 recall any other details. But if you put the var all the way
 to the right and read a declaration right to left, it works:

 int*[] x // x is a array of ptr to ints
 int() f // f is a function returning it
 int*()* f // f is a ptr to function returning ptr to int
 int*()* f,g // f & g are ptrs to function returning ptr to int

 This is only slightly weird if you are used to the current syntax
 but you can easily retrain yourself.

 IMHO, where evolution of C, Scheme and most programming
 languages goes wrong is doing evolutionary design by
 committee. Most users grasp what is easier to use vs what is
 hard but they don't have the aesthetic sense or imagination or
 training to make things simple. And in large groups popularity
 or force of personality or some other irrelevant attribute
 wins not aesthetics. Language evolution IMHO must be done by
 benevolent dictatorship or a guild of like minded people who
 have worked together for a long time! Go seems to have
 adapted that style....

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://minnie.tuhs.org/pipermail/tuhs/attachments/20170513/19d1420b/attachment.html>


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-14  6:12                     ` Steve Johnson
@ 2017-05-14  6:48                       ` Bakul Shah
  2017-05-14 23:06                         ` Ron Natalie
  0 siblings, 1 reply; 48+ messages in thread
From: Bakul Shah @ 2017-05-14  6:48 UTC (permalink / raw)


So the problem was your assumptions didn't match IBM's! Most likely the FORTRAN standard /allowed/ pass by value/result instead of pass by ref.

None of the changes I suggested in my previous email (that focused on arrays in C) would have required a GC or heap. It would've increased programmer convenience and reduced bugs though! 

> On May 13, 2017, at 11:12 PM, Steve Johnson <scj at yaccman.com> wrote:
> 
> I can't resist jumping in here.   My main point is that system coding is a rather different beast than most application programming.  An operating system must be able to handle memory allocation requests from a user without knowing any details of what is requested.  Dennis explicitly left out a heap and garbage collection code in C because he didn't want OS code to be burdened with it.  Similarly with a "real" string type (with concatenation, etc.).
> 
> An example that speaks to me is that of creating a symbol table.  This isn't kernel programming, but consider what is needed:
> A structure that holds the individual table entries
> A tree of lookup tables that reflects the scoping rules of the language -- several tables might need to be searched to find an entry
> A function that looks up a name in a scope, returns the entry if it's defined, and adds a new entry in the appropriate scope if it isn't there yet.
> Statistically a majority of the calls do not change the symbol table, but some do, and you can't tell in advance.  And in the same way, many of the possible scopes where a variable might reside need not be searched.
> 
> So how much of this table should we copy into the lookup function?  The answer seems obvious to me -- none of it...
> 
> Before Unix, Dennis and I and several other people worked on a symbolic algebra system written in FORTRAN.  Dennis wrote a dynamic storage allocator, which was a real feat in FORTRAN, complete with garbage collector.  The goal was to have the program work on the 6 major manufacturers' FORTRANs.  We got it up and running on many of the systems, but did not have easy access to OS 360.   Finally, we were granted the third shift on the OS 360, and ran our program (that had become rather solid by this time...).   It was a disaster -- the brogram ran for a few second and then the OS dies and could not be restarted (turns out the core dump area allotted on the disc was not big enough to hold our program).  
> 
> The problem turned out to be that the IBM compiler did copy in/copy out argument passing, while all the other compilers passed by reference.  If you passed in an argument  that was dynamically allocated, and the system did a garbage collection, all the elements that were still live were moved around but kept their contents intact... until the function returned, and tried to copy the changed value out where that block used to be at the time of the call.
> 
> It took us about 6 months to rewrite the system so we didn't do that -- we had to allocate everything that would be needed first, then do the work, and then free things...
> 
> None of us were fans of copy in/copy out after that experience...
> 
> Steve
> 
> 
> ----- Original Message -----
> From: "Bakul Shah" <bakul at bitblocks.com>
> To:"Lawrence Stewart" <stewart at serissa.com>
> Cc:"tuhs" <tuhs at minnie.tuhs.org>
> Sent:Sat, 13 May 2017 21:24:11 -0700
> Subject:Re: [TUHS] C declarations.
> 
> 
> On Sat, 13 May 2017 21:59:57 EDT Lawrence Stewart <stewart at serissa.com> wrote:
> >
> > * - But I have never been able to remember the syntax for function pointers. > I always "man qsort" to refresh my memory.
> 
> The way I remember:
> 
> given *x[] or *x(), x /sticks/ to the /right/ first. Thus
> 
> int *x[];	// x is array of ptr to int
> int *x();	// x is a function returning ptr to int
> 
> If you don't want a var to stick to its right, separate using
> using parentheses.
> 
> int (*x)[];	// x is a ptr to array of ints
> int (*x)();	// x is a ptr to function returning int
> int *(*x)[];	// x is a ptr to array of ptrs to int
> 
> This sort of also works for multiple variables in one declaration. Given
> 
> int *x, y;	// * /sticks/ to the right (x) first, so not available for y.
> 
> Now if they'd allowed parenthesizing the type, as in
> 
> (int *)x, y;
> 
> we would see that both x & y are of type int *. That would've also allowed
> declaring multiple vars in one declaration where the previous rule applies!
> 
> (int*)(*f,*g)();
> 
> Part of the confusion is * is tacked on at the front while []
> & () at the back of a variable. Someone (Chandy?) had
> proposed unifying this syntax but it didn't go anywhere. I
> think the author used @ in a suffix place though I don't
> recall any other details. But if you put the var all the way
> to the right and read a declaration right to left, it works:
> 
> int*[] x	// x is a array of ptr to ints
> int() f	// f is a function returning it
> int*()* f	// f is a ptr to function returning ptr to int
> int*()* f,g	// f & g are ptrs to function returning ptr to int
> 
> This is only slightly weird if you are used to the current syntax
> but you can easily retrain yourself.
> 
> IMHO, where evolution of C, Scheme and most programming
> languages goes wrong is doing evolutionary design by
> committee. Most users grasp what is easier to use vs what is
> hard but they don't have the aesthetic sense or imagination or
> training to make things simple. And in large groups popularity
> or force of personality or some other irrelevant attribute
> wins not aesthetics. Language evolution IMHO must be done by
> benevolent dictatorship or a guild of like minded people who
> have worked together for a long time! Go seems to have
> adapted that style....

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://minnie.tuhs.org/pipermail/tuhs/attachments/20170513/46d94d99/attachment-0001.html>


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-13 19:05             ` Random832
@ 2017-05-14 13:14               ` Derek Fawcus
  0 siblings, 0 replies; 48+ messages in thread
From: Derek Fawcus @ 2017-05-14 13:14 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 785 bytes --]

On Sat, May 13, 2017 at 03:05:24PM -0400, Random832 wrote:
> On Sat, May 13, 2017, at 08:20, Michael Kjörling wrote:
> > Correct me if I am wrong, but _pass by value_ as opposed to _pass by
> > reference_ requires making a copy, no? That's the whole point, to
> > allow the callee to poke at the value it is given at will.
> 
> If that were the issue, the callee could simply automatically make the
> copy if-and-only-if it needs it.

I recall reading a proposed ABI for C on MIPS which would have done
something similar for passing structs by value,  namely pass a pointer
but allocate local storage space in the callee.  If the callee ever
assigned to the passed struct,  it was to copy the actual values,
then update its pointer.  I don't think that ABI was ever implemented.

DF


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-13 23:21                 ` Dave Horsfall
@ 2017-05-14 14:48                   ` Nemo
  0 siblings, 0 replies; 48+ messages in thread
From: Nemo @ 2017-05-14 14:48 UTC (permalink / raw)


On 13 May 2017 at 19:21, Dave Horsfall <dave at horsfall.org> wrote:
> On Sat, 13 May 2017, Random832 wrote:
>
>> Fortran, for the record, passes nearly everything by reference [...]
>
> And if you passed a constant and the local argument was modified, so was
> the (single instance of) constant...

Probably depends on the implementation.  VAX-FORTRAN passed by
reference (but not on the stack).

Off-topic: I recall a working function that crashed when fed a
constant string.  Spelunking revealed that someone had replaced a
letter-by-letter case-insensitive comparison with a "faster version"
(written in VAX assembler, no less) that converted both arguments to
upper case and then block-compared.

N.


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-14  6:48                       ` Bakul Shah
@ 2017-05-14 23:06                         ` Ron Natalie
  2017-05-14 23:34                           ` Arthur Krewat
  0 siblings, 1 reply; 48+ messages in thread
From: Ron Natalie @ 2017-05-14 23:06 UTC (permalink / raw)


You all are missing the point as to what the cost of passing arrays by value
or what other languages do.

 

C is implicitly a pass/return by value language for EVERY SINGLE POSSIBLE
DATATYPE WITH THE EXCEPTION OF ARRAYS.

Arrays are special for no reason other than it was thought to costly to do
it any otherway.   In fact, had it not been kludged up into a
pseudo-pass-by-reference,

nobody would have probably been the wiser.   It was too hard to pass/return
structs by value either in the initial compilers, but they fixed it to work
exactly that way.

 

So we have this array kludge that works differently than everything else.
Further, due to the kludgosity, it's not even exactly type safe.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://minnie.tuhs.org/pipermail/tuhs/attachments/20170514/d7e5bfc5/attachment.html>


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-14 23:06                         ` Ron Natalie
@ 2017-05-14 23:34                           ` Arthur Krewat
  2017-05-15  0:14                             ` Dan Cross
  0 siblings, 1 reply; 48+ messages in thread
From: Arthur Krewat @ 2017-05-14 23:34 UTC (permalink / raw)


On 5/14/2017 7:06 PM, Ron Natalie wrote:
> array kludge
Is it really a kludge? It's a pointer.

int array[128];

Want to reference the array in a memcpy? Do: memcpy(destination, array, 
sizeof(array));

Want to reference an element in the array? array[element #]

Want to pass (a reference to) said array to a function? function(array)

Not sure what the kludge is.

I think C is more consistent when it comes to arrays than a lot of other 
languages. At least with C you KNOW it's a pointer to the original.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://minnie.tuhs.org/pipermail/tuhs/attachments/20170514/acf3111e/attachment.html>


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-14 23:34                           ` Arthur Krewat
@ 2017-05-15  0:14                             ` Dan Cross
  2017-05-15  0:23                               ` Ron Natalie
  2017-05-15  0:40                               ` Larry McVoy
  0 siblings, 2 replies; 48+ messages in thread
From: Dan Cross @ 2017-05-15  0:14 UTC (permalink / raw)


On Sun, May 14, 2017 at 7:34 PM, Arthur Krewat <krewat at kilonet.net> wrote:

> On 5/14/2017 7:06 PM, Ron Natalie wrote:
>
> array kludge
>
> Is it really a kludge?
>

Yes.

It's a pointer.
>

Of course it is! But that doesn't mean that it SHOULD be, which is the
point.

int array[128];
>
> Want to reference the array in a memcpy? Do: memcpy(destination, array,
> sizeof(array));
>
> Want to reference an element in the array? array[element #]
>
> Want to pass (a reference to) said array to a function? function(array)
>
> Not sure what the kludge is.
>

The kludge is that it works different than everything else for no really
good reason.

I think C is more consistent when it comes to arrays than a lot of other
> languages. At least with C you KNOW it's a pointer to the original.
>

Sure! But if someone had told you, back when you first learned C, that it
was an array and had value semantics, would you have thought THAT was
strange? "If you want a pointer to the array, use the address operator on
the array and pass that; that'll behave like a 'foo*' pointer for an array
of foo. Most people do this for efficiency."

The point is that it's a thought exercise. It's not that folks don't
understand how C works now or the semantics of array-decay-to-pointer; it's
just that folks can also imagine a world where things had been done
differently. That world doesn't exist, but we can still imagine it.

        - Dan C.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://minnie.tuhs.org/pipermail/tuhs/attachments/20170514/42e2d44f/attachment.html>


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-15  0:14                             ` Dan Cross
@ 2017-05-15  0:23                               ` Ron Natalie
  2017-05-15  3:43                                 ` Random832
  2017-05-15  0:40                               ` Larry McVoy
  1 sibling, 1 reply; 48+ messages in thread
From: Ron Natalie @ 2017-05-15  0:23 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 547 bytes --]

It's a pointer.

 

Ø   Of course it is! But that doesn't mean that it SHOULD be, which is the point.

 

Actually, it is **Not a pointer**, it gets passed as a pointer, but it is an array on both ends.

 

 

The implicit conversion of the array name to a pointer to its first item is a different issue.   This bothers me less, but it’s still hokie in my opinion.

 

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://minnie.tuhs.org/pipermail/tuhs/attachments/20170514/6a91ab9a/attachment-0001.html>


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-15  0:14                             ` Dan Cross
  2017-05-15  0:23                               ` Ron Natalie
@ 2017-05-15  0:40                               ` Larry McVoy
  2017-05-15  2:00                                 ` Nevin Liber
  2017-05-15 10:21                                 ` Tony Finch
  1 sibling, 2 replies; 48+ messages in thread
From: Larry McVoy @ 2017-05-15  0:40 UTC (permalink / raw)


On Sun, May 14, 2017 at 08:14:47PM -0400, Dan Cross wrote:
> The kludge is that it works different than everything else for no really
> good reason.

I'd be curious what Steve thinks about all this, I know he weighed in 
a bit, but does he think that Dennis / Brian/ Ken regret this design choice?

Personally, I can easily see why they did it.  C doesn't really have a lot
of behind-the-scenes magic, it can easily be viewed as a pleasant way to
do portable code that sits directly on the hardware, no frameworks, no
garbage collector, no magic.  It's predictable in ways that higher level
languages are not.  That's one of the things I like about C, I can reason
about it.

But I suspect it was more basic than that.  They were running on 16 bit 
pretty slow machines and having a pass by value model for arrays just
didn't make any sense.  *Everyone* would pass by reference so why bother
having a pass by value model?  If you really, really wanted that you 
could get it

    int salaries[100];
    int payroll = add_them_up(malloc_and_copy(salaries, sizeof(salaries));

But any sane person in that day and age would go "why on God's green earth
would you do that?  It's slow.  Just don't change the salaries array and
you'll be fine".

Think about all the str* stuff - you really want to malloc and free that?
It would have killed performance.

Personally I think they looked at it, said "everyone will use references
for arrays anyway, let's make them references by default".

I get that it is not clean and pure and doesn't match how other types work,
I do see that, but I also see that their choice made a ton of sense at the
time.  And maybe still does.  It's not the same as the other types because
the other types are, typically, small.  Arrays can be big, really big.

--lm


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-15  0:40                               ` Larry McVoy
@ 2017-05-15  2:00                                 ` Nevin Liber
  2017-05-15 10:21                                 ` Tony Finch
  1 sibling, 0 replies; 48+ messages in thread
From: Nevin Liber @ 2017-05-15  2:00 UTC (permalink / raw)


On Sun, May 14, 2017 at 7:40 PM, Larry McVoy <lm at mcvoy.com> wrote:

> I get that it is not clean and pure and doesn't match how other types work,
> I do see that, but I also see that their choice made a ton of sense at the
> time.  And maybe still does.  It's not the same as the other types because
> the other types are, typically, small.  Arrays can be big, really big.
>

IIRC, you couldn't pass or return structs either.  Also, no function
prototypes, so passing data of different sizes would have been a bit more
difficult.
-- 
 Nevin ":-)" Liber  <mailto:nevin at eviloverlord.com>  +1-847-691-1404
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://minnie.tuhs.org/pipermail/tuhs/attachments/20170514/8912a30f/attachment.html>


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-15  0:23                               ` Ron Natalie
@ 2017-05-15  3:43                                 ` Random832
  0 siblings, 0 replies; 48+ messages in thread
From: Random832 @ 2017-05-15  3:43 UTC (permalink / raw)


On Sun, May 14, 2017, at 20:23, Ron Natalie wrote:
> Actually, it is **Not a pointer**, it gets passed as a pointer, but it is
> an array on both ends.

I'm not sure what you mean by "on both ends". It is a pointer in the
function. sizeof(dst) is 2, not 256, even if it were declared as int
dst[128].

On Sun, May 14, 2017, at 19:34, Arthur Krewat wrote:
> Is it really a kludge? It's a pointer.
> 
> int array[128];
> 
> Want to reference the array in a memcpy? Do: memcpy(destination, array, 
> sizeof(array));

The argument is that that should have to be memcpy(&destination, &array,
sizeof(array)), the same as if you were copying between two structs.


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-14  4:24                   ` Bakul Shah
  2017-05-14  6:12                     ` Steve Johnson
@ 2017-05-15  4:35                     ` Dave Horsfall
  2017-05-15  4:54                       ` Bakul Shah
  2017-05-15 12:58                       ` Michael Kjörling
  1 sibling, 2 replies; 48+ messages in thread
From: Dave Horsfall @ 2017-05-15  4:35 UTC (permalink / raw)


On Sat, 13 May 2017, Bakul Shah wrote:

> int*()* f	// f is a ptr to function returning ptr to int

Nope.

    aneurin% cdecl
    Type `help' or `?' for help
    explain int*()* f
    syntax error
    declare f as ptr to function returning ptr to int
    int *(*f)()

(Sigh; "cdecl" really needs to print a "> " prompt or something.)

-- 
Dave Horsfall DTM (VK2KFU)  "Those who don't understand security will suffer."


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-15  4:35                     ` Dave Horsfall
@ 2017-05-15  4:54                       ` Bakul Shah
  2017-05-15  5:01                         ` Dave Horsfall
  2017-05-15 12:58                       ` Michael Kjörling
  1 sibling, 1 reply; 48+ messages in thread
From: Bakul Shah @ 2017-05-15  4:54 UTC (permalink / raw)


On Mon, 15 May 2017 14:35:34 +1000 Dave Horsfall <dave at horsfall.org> wrote:
> On Sat, 13 May 2017, Bakul Shah wrote:
> 
> > int*()* f	// f is a ptr to function returning ptr to int
> 
> Nope.
> 
>     aneurin% cdecl
>     Type `help' or `?' for help
>     explain int*()* f
>     syntax error
>     declare f as ptr to function returning ptr to int
>     int *(*f)()
> 
> (Sigh; "cdecl" really needs to print a "> " prompt or something.)

Sorry, I was less than clear.  I was just doing a thought
experiment about an alternate declaration syntax.  Requoting
from my email:

                             But if you put the var all the way
  to the right and read a declaration right to left, it works:

Basically suggesting that if all type machinery *preceded* an
object declaration (including for functions), we don't need any
parentheses and declarations are very easy to understand --
you just read a declaration from right to left. So no need
for cdel!  Too late for this, of course!


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-15  4:54                       ` Bakul Shah
@ 2017-05-15  5:01                         ` Dave Horsfall
  0 siblings, 0 replies; 48+ messages in thread
From: Dave Horsfall @ 2017-05-15  5:01 UTC (permalink / raw)


On Sun, 14 May 2017, Bakul Shah wrote:

> > Nope.
> > 
> >     aneurin% cdecl
> >     Type `help' or `?' for help
> >     explain int*()* f
> >     syntax error
> >     declare f as ptr to function returning ptr to int
> >     int *(*f)()
> 
> Sorry, I was less than clear.  I was just doing a thought
> experiment about an alternate declaration syntax.  Requoting
> from my email:

Sorry - entirely my fault (which I'd realised just *after* I'd sent it, of 
course).  Yes, your idea is a lot better.

-- 
Dave Horsfall DTM (VK2KFU)  "Those who don't understand security will suffer."


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-15  0:40                               ` Larry McVoy
  2017-05-15  2:00                                 ` Nevin Liber
@ 2017-05-15 10:21                                 ` Tony Finch
  1 sibling, 0 replies; 48+ messages in thread
From: Tony Finch @ 2017-05-15 10:21 UTC (permalink / raw)


Larry McVoy <lm at mcvoy.com> wrote:
> On Sun, May 14, 2017 at 08:14:47PM -0400, Dan Cross wrote:
> > The kludge is that it works different than everything else for no really
> > good reason.
>
> I'd be curious what Steve thinks about all this, I know he weighed in
> a bit, but does he think that Dennis / Brian/ Ken regret this design choice?

I wonder how much of it was due to evolving in stages from BCPL, where
everything is a word, and structs and arrays are just pointers (with maybe
an allocation of space for the pointer to point to).

And C couldn't pass structs by value for quite a long time.

Tony.
-- 
f.anthony.n.finch  <dot at dotat.at>  http://dotat.at/  -  I xn--zr8h punycode
Fair Isle, Faeroes: Southeast 5 or 6, increasing 7 or gale 8 for a time.
Moderate or rough, occasionally very rough in Faeroes. Fair then rain with fog
patches. Good, becoming moderate or very poor.


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-15  4:35                     ` Dave Horsfall
  2017-05-15  4:54                       ` Bakul Shah
@ 2017-05-15 12:58                       ` Michael Kjörling
  2017-05-15 16:58                         ` Dave Horsfall
  1 sibling, 1 reply; 48+ messages in thread
From: Michael Kjörling @ 2017-05-15 12:58 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1002 bytes --]

On 15 May 2017 14:35 +1000, from dave at horsfall.org (Dave Horsfall):
> (Sigh; "cdecl" really needs to print a "> " prompt or something.)

It does print "cdecl> " as a prompt on my system.

   $ cdecl
   Type `help' or `?' for help
   cdecl> explain int*()* f
   syntax error
   cdecl> declare f as ptr to function returning ptr to int
   int *(*f)()
   cdecl> ^D
   $ 

However, running it with -q turns this off:

   $ cdecl -q
   declare f as ptr to function returning ptr to int
   int *(*f)()
   ^D
   $ 

The man page for mine says 2.5, Jan 1996, and the Debian package
version says 2.5-11. 1996 in 2017 is old even for Debian.

Are you sure that you don't have a stray alias somewhere, or something
that might be causing it to misdetect as not running in a terminal?

-- 
Michael Kjörling • https://michael.kjorling.se • michael at kjorling.se
                 “People who think they know everything really annoy
                 those of us who know we don’t.” (Bjarne Stroustrup)


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-15 12:58                       ` Michael Kjörling
@ 2017-05-15 16:58                         ` Dave Horsfall
  2017-05-15 19:00                           ` [TUHS] cdecl (Re: " Bakul Shah
  0 siblings, 1 reply; 48+ messages in thread
From: Dave Horsfall @ 2017-05-15 16:58 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 864 bytes --]

On Mon, 15 May 2017, Michael Kjörling wrote:

> It does print "cdecl> " as a prompt on my system.
[...]
> The man page for mine says 2.5, Jan 1996, and the Debian package
> version says 2.5-11. 1996 in 2017 is old even for Debian.

I've got 2.5 as well (on FreeBSD 10.3), and "set prompt" has no effect.  
I even rebuilt it in case there was a later version.

> Are you sure that you don't have a stray alias somewhere, or something 
> that might be causing it to misdetect as not running in a terminal?

aneurin% cdecl
Type `help' or `?' for help
set prompt
set options
[...]
Current set values are:
	 noprompt
	   interactive

WTF?

I'll fire up GDB and have a poke around (once I'm properly awake; I only 
got up for a glass of water, and couldn't help but check my email).


-- 
Dave Horsfall DTM (VK2KFU)  "Those who don't understand security will suffer."


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] cdecl (Re:  C declarations.
  2017-05-15 16:58                         ` Dave Horsfall
@ 2017-05-15 19:00                           ` Bakul Shah
  2017-05-15 22:52                             ` Dave Horsfall
  0 siblings, 1 reply; 48+ messages in thread
From: Bakul Shah @ 2017-05-15 19:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1107 bytes --]

pkg upgrade cdecl

2.5 didn't show a prompt but 3.1.3 does (though the prompt is in /green/. Sigh...)

> On May 15, 2017, at 9:58 AM, Dave Horsfall <dave at horsfall.org> wrote:
> 
>> On Mon, 15 May 2017, Michael Kjörling wrote:
>> 
>> It does print "cdecl> " as a prompt on my system.
> [...]
>> The man page for mine says 2.5, Jan 1996, and the Debian package
>> version says 2.5-11. 1996 in 2017 is old even for Debian.
> 
> I've got 2.5 as well (on FreeBSD 10.3), and "set prompt" has no effect.  
> I even rebuilt it in case there was a later version.
> 
>> Are you sure that you don't have a stray alias somewhere, or something 
>> that might be causing it to misdetect as not running in a terminal?
> 
> aneurin% cdecl
> Type `help' or `?' for help
> set prompt
> set options
> [...]
> Current set values are:
>     noprompt
>       interactive
> 
> WTF?
> 
> I'll fire up GDB and have a poke around (once I'm properly awake; I only 
> got up for a glass of water, and couldn't help but check my email).
> 
> 
> -- 
> Dave Horsfall DTM (VK2KFU)  "Those who don't understand security will suffer."



^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] cdecl (Re:  C declarations.
  2017-05-15 19:00                           ` [TUHS] cdecl (Re: " Bakul Shah
@ 2017-05-15 22:52                             ` Dave Horsfall
  0 siblings, 0 replies; 48+ messages in thread
From: Dave Horsfall @ 2017-05-15 22:52 UTC (permalink / raw)


On Mon, 15 May 2017, Bakul Shah wrote:

> pkg upgrade cdecl

Didn't work; all my packages are up to date, so I guess you're running 
FreeBSD 11 or something?

> 2.5 didn't show a prompt but 3.1.3 does (though the prompt is in 
> /green/. Sigh...)

I'll wait for 3.1.3 to be ported then, although I might bash ahead with 
GDB anyway.

-- 
Dave Horsfall DTM (VK2KFU)  "Those who don't understand security will suffer."


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-15 18:47 Steve Johnson
  2017-05-15 19:54 ` Bakul Shah
@ 2017-05-16  7:25 ` George Ross
  1 sibling, 0 replies; 48+ messages in thread
From: George Ross @ 2017-05-16  7:25 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1378 bytes --]

> ...  When you
> submitted a card deck in the early days, you had to include both the
> function definition and the data--the function was compiled, the data
> was read, and, for the most part there were no significant side
> effects (just a printout, and maybe some stuff on mag tape).

In the late 1970s I had a summer job which involved writing FORTRAN 
programs to analyse card decks.  This was on some IBM machine, which had a 
combi card punch/reader.  On one run the program loaded and compiled, and 
the first two data cards went through.  Then the machine crashed.

After a bit of head-scratching, I realised that it was because the punch 
station came immediately before the read station, and there was a small 
typo in the program.  It processed the first data card, but rather than 
logging to the printer it overpunched the second card instead resulting in 
an invalid hole combination.  That card then went into the read station, 
and the machine didn't like it...
-- 
George D M Ross MSc PhD CEng MBCS CITP, University of Edinburgh,
School of Informatics, 10 Crichton Street, Edinburgh, Scotland, EH8 9AB
Mail: gdmr at inf.ed.ac.uk   Voice: 0131 650 5147   Fax: 0131 650 6899
PGP: 1024D/AD758CC5  B91E D430 1E0D 5883 EF6A  426C B676 5C2B AD75 8CC5

The University of Edinburgh is a charitable body, registered in
Scotland, with registration number SC005336.




^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-15 18:47 Steve Johnson
@ 2017-05-15 19:54 ` Bakul Shah
  2017-05-16  7:25 ` George Ross
  1 sibling, 0 replies; 48+ messages in thread
From: Bakul Shah @ 2017-05-15 19:54 UTC (permalink / raw)


Pascal was designed in 1967-69 and its report came out in 1970. It is of similar complexity (the first self compiling compiler was about 4500 lines, IIRC). It had n dimensional fixed size arrays and structures (records). Allowing any parameter of any type to be a ref param meant you didn't have to copy if you didn't want to. And there is no hidden magic, no GC. I guess it wasn't much known in the US then so not much scope for stealing ideas.... I guess the difference was that Wirth started with Algol W while Ritchie stated with B and BCPL.

Unlike pascal C had the address of (&) operator so C could've only allow passing pointers to them. This would've been less "magic" and much cleaner. And from there a ref parameter is just a small step! To me your earlier comment made more sense - C was seen as a system programming language not an application programming one. For it passing strings and memory blocks was enough. Earlier I had wondered if dmr et al had a more Fortran like array model in mind and punted on it as it would complicate the language.

> On May 15, 2017, at 11:47 AM, Steve Johnson <scj at yaccman.com> wrote:
> 
> 
> Some interesting comments:
> 
>     "You all are missing the point as to what the cost of passing arrays by value or what other languages do"
> 
> I don't think so.  To me the issues is that the model of what it means to compute has changed since the punch-card days.  When you submitted a card deck in the early days, you had to include both the function definition and the data--the function was compiled, the data was read, and, for the most part there were no significant side effects (just a printout, and maybe some stuff on mag tape).
> 
> This was a model that had served mathematics well for centuries, and it was very easy to understand.  Functional programming people still like it a lot...
> 
> However, with the introduction of permanent file systems, a new paradigm came into being.  Now, interactions with the computer looked more like database transactions:  Load your program, change a few lines, put it back, and then call 'make'.  Trying to describe this with a purely functional model leads to absurdities like:
> 
>      file_system = edit( file_system, file_selector, editing_commands );
> 
> In fact, the editing commands can change files, create new ones, and even delete files.  There is no reasonable way to handle any realistic file systems with this model (let alone the Internet!)
> 
> In C's early days, we were just getting into the new world.  Call by value for arrays would have been expensive or impossible on the machine with just a few kilobytes of memory for program + data.  So we didn't do it.
> 
> Structures were initially handled like arrays, but the compiler chose to make a local copy when passed a structure pointer.  This copy was, at one time, in static memory, which caused some problems.  Later, it went on the stack.  It wasn't much used...
> 
> This changed when the Blit terminal project was in place.  It was just too attractive on a 68000 to write
> 
>     struct pt = {  int x;  int y }        /* when int was 16-bits */
> 
> and I made PCC pass small structures like this in registers, like other arguments.  I seem to remember a dramatic speedup (2X or so) from doing this...
> 
> 
> "(did) Dennis / Brian/ Ken regret this design choice?
> 
> Not that I recall.  Of course, we all had bugs in this area.  But I think the lack of subscript range checking was a more serious problem than using pointers in the first place.  And, indeed, for a few of the pioneers, BCPL had done exactly the same thing.  
> 
> 
> 
> Steve
> 
> 
> 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://minnie.tuhs.org/pipermail/tuhs/attachments/20170515/8e372208/attachment-0001.html>


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
@ 2017-05-15 18:47 Steve Johnson
  2017-05-15 19:54 ` Bakul Shah
  2017-05-16  7:25 ` George Ross
  0 siblings, 2 replies; 48+ messages in thread
From: Steve Johnson @ 2017-05-15 18:47 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 2633 bytes --]



	Some interesting comments:

	    "You all are missing the point as to what the cost of passing
arrays by value or what other languages do"

	I don't think so.  To me the issues is that the model of what it
means to compute has changed since the punch-card days.  When you
submitted a card deck in the early days, you had to include both the
function definition and the data--the function was compiled, the data
was read, and, for the most part there were no significant side
effects (just a printout, and maybe some stuff on mag tape).

	This was a model that had served mathematics well for centuries, and
it was very easy to understand.  Functional programming people still
like it a lot...

	However, with the introduction of permanent file systems, a new
paradigm came into being.  Now, interactions with the computer looked
more like database transactions:  Load your program, change a few
lines, put it back, and then call 'make'.  Trying to describe this
with a purely functional model leads to absurdities like:

	     file_system = edit( file_system, file_selector,
editing_commands );

	In fact, the editing commands can change files, create new ones, and
even delete files.  There is no reasonable way to handle any
realistic file systems with this model (let alone the Internet!)

	In C's early days, we were just getting into the new world.  Call by
value for arrays would have been expensive or impossible on the
machine with just a few kilobytes of memory for program + data.  So
we didn't do it.

	Structures were initially handled like arrays, but the compiler chose
to make a local copy when passed a structure pointer.  This copy was,
at one time, in static memory, which caused some problems.  Later, it
went on the stack.  It wasn't much used...

	This changed when the Blit terminal project was in place.  It was
just too attractive on a 68000 to write

	    struct pt = {  int x;  int y }        /* when int was
16-bits */

	and I made PCC pass small structures like this in registers, like
other arguments.  I seem to remember a dramatic speedup (2X or so)
from doing this...

"(did) Dennis / Brian/ Ken regret this design choice?

	Not that I recall.  Of course, we all had bugs in this area.  But I
think the lack of subscript range checking was a more serious problem
than using pointers in the first place.  And, indeed, for a few of
the pioneers, BCPL had done exactly the same thing.  

	Steve


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://minnie.tuhs.org/pipermail/tuhs/attachments/20170515/3b53b088/attachment.html>


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-13 23:11 Richard Tobin
@ 2017-05-15  6:46 ` Tim Bradshaw
  0 siblings, 0 replies; 48+ messages in thread
From: Tim Bradshaw @ 2017-05-15  6:46 UTC (permalink / raw)


On 14 May 2017, at 00:11, Richard Tobin <richard at inf.ed.ac.uk> wrote:
> 
>  If a subprogram reference causes a dummy argument in the referenced
>  subprogram to become associated with another dummy argument in the
>  referenced subprogram, neither dummy argument may become defined
>  during execution of that subprogram.

I think the purpose of that is to allow compilers to assume that if you pass two array arguments (say) to a routine then they are really different chunks of memory, so it can optimize things (ie it does not need to worry about the various hazards that happen if they are secretly the same memory).


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
  2017-05-14 14:11 Doug McIlroy
@ 2017-05-14 14:58 ` Steve Nickolas
  0 siblings, 0 replies; 48+ messages in thread
From: Steve Nickolas @ 2017-05-14 14:58 UTC (permalink / raw)


On Sun, 14 May 2017, Doug McIlroy wrote:

>> Are there languages that copy arrays in function calls defaultly?
>
>> Pascal is an example.
>
> Pascal's var convention, where the distinction between value
> and reference is made once and for all for each argument of
> each function, is sound. The flexibility of PL/I, where the
> distinction is made at every call (parenthesize the name to
> pass an array by value) is finicky, though utterly general.

QuickBasic uses the ( ) trick too.

>> Where is all that [memory]  going to come from if you pass a
>> large array on a memory-constrained system of specs common back in the
>> days when C was designed
>
> Amusingly, under the customary linkage method in the even earlier
> days when Fortran was designed, pass-by-reference entailed a big
> overhead that could easily dominate pass-by-value for small arrays.
>
> [In the beginning, when CPUs had only one register, subroutine
> preambles plugged the reference into every mention of that variable
> throughout the body of the subroutine. This convention persisted
> in Fortran, which was designed for a machine with three index
> registered. Since reference variables were sometimes necessary
> (think of swap(a,b) for example) they were made standard.]
>
> Doug
>

Three! O_O That's a lot, if you're used to the 6502 and its mere *two* 
index registers.

-uso.


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
@ 2017-05-14 14:11 Doug McIlroy
  2017-05-14 14:58 ` Steve Nickolas
  0 siblings, 1 reply; 48+ messages in thread
From: Doug McIlroy @ 2017-05-14 14:11 UTC (permalink / raw)


> Are there languages that copy arrays in function calls defaultly?

> Pascal is an example.

Pascal's var convention, where the distinction between value
and reference is made once and for all for each argument of
each function, is sound. The flexibility of PL/I, where the
distinction is made at every call (parenthesize the name to
pass an array by value) is finicky, though utterly general.

> Where is all that [memory]  going to come from if you pass a
> large array on a memory-constrained system of specs common back in the
> days when C was designed

Amusingly, under the customary linkage method in the even earlier
days when Fortran was designed, pass-by-reference entailed a big
overhead that could easily dominate pass-by-value for small arrays.

[In the beginning, when CPUs had only one register, subroutine
preambles plugged the reference into every mention of that variable
throughout the body of the subroutine. This convention persisted
in Fortran, which was designed for a machine with three index
registered. Since reference variables were sometimes necessary
(think of swap(a,b) for example) they were made standard.] 

Doug


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
@ 2017-05-13 23:11 Richard Tobin
  2017-05-15  6:46 ` Tim Bradshaw
  0 siblings, 1 reply; 48+ messages in thread
From: Richard Tobin @ 2017-05-13 23:11 UTC (permalink / raw)


> Fortran, for the record, passes nearly everything by reference

Sort of.  The Fortran 77 standard imposes restrictions that appear to
be intended to allow the implementation to pass by value-and-result
(i.e. values are copied in, and copied back at return).  In particular
it disallows aliasing that would allow you to distinguish between
the two methods:

  If a subprogram reference causes a dummy argument in the referenced
  subprogram to become associated with another dummy argument in the
  referenced subprogram, neither dummy argument may become defined
  during execution of that subprogram.

http://www.fortran.com/F77_std/rjcnf-15.html#sh-15.9.3.6

-- Richard

-- 
The University of Edinburgh is a charitable body, registered in
Scotland, with registration number SC005336.



^ permalink raw reply	[flat|nested] 48+ messages in thread

* [TUHS] C declarations.
@ 2017-05-12 14:04 Richard Tobin
  0 siblings, 0 replies; 48+ messages in thread
From: Richard Tobin @ 2017-05-12 14:04 UTC (permalink / raw)


> The problem with that is that * doesn't really bind to the type name. 
> It binds to the variable.
> 
> char* cp1, cp2;   // cp1 is pointer to char,   cp2 is just a char.
> 
> I always found it confusing that the * is used to indicate an pointer
> here, where as when you want to change an lvalue to a pointer, you use
> &.

The way to read it is that you are declaring *cp1 as a char.

-- Richard

-- 
The University of Edinburgh is a charitable body, registered in
Scotland, with registration number SC005336.



^ permalink raw reply	[flat|nested] 48+ messages in thread

end of thread, other threads:[~2017-05-16  7:25 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-11 21:49 [TUHS] C declarations Ron Natalie
2017-05-11 22:01 ` Arthur Krewat
2017-05-11 23:44   ` Dave Horsfall
2017-05-11 22:03 ` David Arnold
2017-05-11 22:32   ` Larry McVoy
2017-05-11 22:41     ` Ron Natalie
2017-05-13  1:24       ` Larry McVoy
2017-05-13  2:45         ` Ron Natalie
2017-05-13 12:20           ` Michael Kjörling
2017-05-13 12:35             ` Tim Bradshaw
2017-05-13 12:42               ` Michael Kjörling
2017-05-13 15:36                 ` Stephen Kitt
2017-05-14  1:59                 ` Lawrence Stewart
2017-05-14  2:23                   ` Dave Horsfall
2017-05-14  4:24                   ` Bakul Shah
2017-05-14  6:12                     ` Steve Johnson
2017-05-14  6:48                       ` Bakul Shah
2017-05-14 23:06                         ` Ron Natalie
2017-05-14 23:34                           ` Arthur Krewat
2017-05-15  0:14                             ` Dan Cross
2017-05-15  0:23                               ` Ron Natalie
2017-05-15  3:43                                 ` Random832
2017-05-15  0:40                               ` Larry McVoy
2017-05-15  2:00                                 ` Nevin Liber
2017-05-15 10:21                                 ` Tony Finch
2017-05-15  4:35                     ` Dave Horsfall
2017-05-15  4:54                       ` Bakul Shah
2017-05-15  5:01                         ` Dave Horsfall
2017-05-15 12:58                       ` Michael Kjörling
2017-05-15 16:58                         ` Dave Horsfall
2017-05-15 19:00                           ` [TUHS] cdecl (Re: " Bakul Shah
2017-05-15 22:52                             ` Dave Horsfall
2017-05-13 13:46               ` [TUHS] " Hellwig Geisse
2017-05-13 19:08               ` Random832
2017-05-13 23:21                 ` Dave Horsfall
2017-05-14 14:48                   ` Nemo
2017-05-13 19:05             ` Random832
2017-05-14 13:14               ` Derek Fawcus
2017-05-12  0:15     ` Bakul Shah
2017-05-12  2:41       ` Theo Pavlidis
2017-05-12 14:04 Richard Tobin
2017-05-13 23:11 Richard Tobin
2017-05-15  6:46 ` Tim Bradshaw
2017-05-14 14:11 Doug McIlroy
2017-05-14 14:58 ` Steve Nickolas
2017-05-15 18:47 Steve Johnson
2017-05-15 19:54 ` Bakul Shah
2017-05-16  7:25 ` George Ross

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).