* [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; 40+ 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] 40+ 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; 40+ 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] 40+ messages in thread
* [TUHS] C declarations. 2017-05-11 22:01 ` Arthur Krewat @ 2017-05-11 23:44 ` Dave Horsfall 0 siblings, 0 replies; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ messages in thread
* [TUHS] C declarations. 2017-05-15 0:23 ` Ron Natalie @ 2017-05-15 3:43 ` Random832 0 siblings, 0 replies; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ messages in thread
* [TUHS] C declarations. 2017-05-15 4:54 ` Bakul Shah @ 2017-05-15 5:01 ` Dave Horsfall 0 siblings, 0 replies; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ 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; 40+ 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] 40+ messages in thread
* [TUHS] C declarations. 2017-05-13 23:21 ` Dave Horsfall @ 2017-05-14 14:48 ` Nemo 0 siblings, 0 replies; 40+ 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] 40+ 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; 40+ 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] 40+ messages in thread
* [TUHS] C declarations. 2017-05-13 19:05 ` Random832 @ 2017-05-14 13:14 ` Derek Fawcus 0 siblings, 0 replies; 40+ 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] 40+ 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; 40+ 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] 40+ messages in thread
* [TUHS] C declarations. 2017-05-12 0:15 ` Bakul Shah @ 2017-05-12 2:41 ` Theo Pavlidis 0 siblings, 0 replies; 40+ 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] 40+ messages in thread
end of thread, other threads:[~2017-05-15 22:52 UTC | newest] Thread overview: 40+ 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
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).