Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #73016 > unrolled thread
| Started by | Alla _ <modelling.data@gmail.com> |
|---|---|
| First post | 2015-10-16 00:49 -0700 |
| Last post | 2015-10-17 13:59 -0700 |
| Articles | 20 on this page of 77 — 14 participants |
Back to article view | Back to comp.lang.c
Pointers, constant values Alla _ <modelling.data@gmail.com> - 2015-10-16 00:49 -0700
Re: Pointers, constant values Philip Lantz <prl@canterey.us> - 2015-10-16 01:49 -0700
Re: Pointers, constant values James Kuyper <jameskuyper@verizon.net> - 2015-10-16 09:41 -0400
Re: Pointers, constant values supercat@casperkitty.com - 2015-10-16 08:55 -0700
Re: Pointers, constant values Keith Thompson <kst-u@mib.org> - 2015-10-16 08:25 -0700
Re: Pointers, constant values supercat@casperkitty.com - 2015-10-16 09:11 -0700
Re: Pointers, constant values Keith Thompson <kst-u@mib.org> - 2015-10-16 12:06 -0700
Re: Pointers, constant values supercat@casperkitty.com - 2015-10-16 12:55 -0700
Re: Pointers, constant values Bartc <bc@freeuk.com> - 2015-10-16 17:49 +0100
Re: Pointers, constant values Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2015-10-16 13:23 -0400
Re: Pointers, constant values Bartc <bc@freeuk.com> - 2015-10-16 19:34 +0100
Re: Pointers, constant values supercat@casperkitty.com - 2015-10-16 12:05 -0700
Re: Pointers, constant values Keith Thompson <kst-u@mib.org> - 2015-10-16 12:18 -0700
Re: Pointers, constant values Keith Thompson <kst-u@mib.org> - 2015-10-16 12:13 -0700
Re: Pointers, constant values Bartc <bc@freeuk.com> - 2015-10-16 20:33 +0100
Re: Pointers, constant values Keith Thompson <kst-u@mib.org> - 2015-10-16 13:01 -0700
Re: Pointers, constant values Bartc <bc@freeuk.com> - 2015-10-16 21:09 +0100
Re: Pointers, constant values Keith Thompson <kst-u@mib.org> - 2015-10-16 13:41 -0700
Re: Pointers, constant values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-16 21:07 +0100
Re: Pointers, constant values Bartc <bc@freeuk.com> - 2015-10-16 21:20 +0100
Re: Pointers, constant values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-16 22:02 +0100
Re: Pointers, constant values Bartc <bc@freeuk.com> - 2015-10-16 22:21 +0100
Re: Pointers, constant values supercat@casperkitty.com - 2015-10-16 14:39 -0700
Re: Pointers, constant values Keith Thompson <kst-u@mib.org> - 2015-10-16 15:26 -0700
Re: Pointers, constant values supercat@casperkitty.com - 2015-10-16 15:44 -0700
Re: Pointers, constant values Keith Thompson <kst-u@mib.org> - 2015-10-16 16:58 -0700
Re: Pointers, constant values supercat@casperkitty.com - 2015-10-16 17:28 -0700
Re: Pointers, constant values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-16 22:50 +0100
Re: Pointers, constant values supercat@casperkitty.com - 2015-10-16 15:14 -0700
Re: Pointers, constant values Bartc <bc@freeuk.com> - 2015-10-17 01:23 +0100
Re: Pointers, constant values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-17 19:39 +0100
Re: Pointers, constant values Bartc <bc@freeuk.com> - 2015-10-17 22:42 +0100
Re: Pointers, constant values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-18 00:31 +0100
Re: Pointers, constant values Bartc <bc@freeuk.com> - 2015-10-18 02:11 +0100
Re: Pointers, constant values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-18 11:59 +0100
Re: Pointers, constant values Bartc <bc@freeuk.com> - 2015-10-18 12:12 +0100
Re: Pointers, constant values Bartc <bc@freeuk.com> - 2015-10-18 12:28 +0100
Re: Pointers, constant values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-18 23:16 +0100
Re: Pointers, constant values Bartc <bc@freeuk.com> - 2015-10-18 23:34 +0100
Re: Pointers, constant values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-19 01:45 +0100
Re: Pointers, constant values Bartc <bc@freeuk.com> - 2015-10-19 11:51 +0100
Re: Pointers, constant values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-19 12:55 +0100
Re: Pointers, constant values Bartc <bc@freeuk.com> - 2015-10-19 13:51 +0100
Re: Pointers, constant values Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-10-19 06:02 -0700
Re: Pointers, constant values supercat@casperkitty.com - 2015-10-19 07:02 -0700
Re: Pointers, constant values Bartc <bc@freeuk.com> - 2015-10-19 15:39 +0100
Re: Pointers, constant values supercat@casperkitty.com - 2015-10-19 08:54 -0700
Re: Pointers, constant values Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-10-19 09:14 -0700
Re: Pointers, constant values supercat@casperkitty.com - 2015-10-19 10:21 -0700
Re: Pointers, constant values Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-10-19 12:57 -0700
Re: Pointers, constant values glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-19 21:20 +0000
Re: Pointers, constant values supercat@casperkitty.com - 2015-10-20 20:50 -0700
Re: Pointers, constant values glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-21 04:58 +0000
Re: Pointers, constant values Keith Thompson <kst-u@mib.org> - 2015-10-19 08:40 -0700
Re: Pointers, constant values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-19 20:17 +0100
Re: Pointers, constant values supercat@casperkitty.com - 2015-10-17 16:44 -0700
Re: Pointers, constant values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-18 11:52 +0100
Re: Pointers, constant values Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-10-18 05:15 -0700
Re: Pointers, constant values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-18 21:54 +0100
Re: Pointers, constant values Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-10-18 16:09 -0700
Re: Pointers, constant values supercat@casperkitty.com - 2015-10-18 07:55 -0700
Re: Pointers, constant values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-18 21:47 +0100
Re: Pointers, constant values supercat@casperkitty.com - 2015-10-18 15:37 -0700
Re: Pointers, constant values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-19 00:10 +0100
Re: Pointers, constant values supercat@casperkitty.com - 2015-10-18 19:04 -0700
Re: Pointers, constant values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-16 21:13 +0100
Re: Pointers, constant values Ian Collins <ian-news@hotmail.com> - 2015-10-17 11:27 +1300
Re: Pointers, constant values Bartc <bc@freeuk.com> - 2015-10-17 00:56 +0100
Re: Pointers, constant values Les Cargill <lcargill99@comcast.com> - 2015-10-16 12:37 -0500
Re: Pointers, constant values James Kuyper <jameskuyper@verizon.net> - 2015-10-16 14:22 -0400
Re: Pointers, constant values Jorgen Grahn <grahn+nntp@snipabacken.se> - 2015-10-16 18:57 +0000
Re: Pointers, constant values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-16 20:40 +0100
Re: Pointers, constant values Jorgen Grahn <grahn+nntp@snipabacken.se> - 2015-10-16 20:46 +0000
Re: Pointers, constant values Keith Thompson <kst-u@mib.org> - 2015-10-16 14:24 -0700
Re: Pointers, constant values Jorgen Grahn <grahn+nntp@snipabacken.se> - 2015-10-19 12:43 +0000
Re: Pointers, constant values Siri Cruz <chine.bleu@yahoo.com> - 2015-10-16 13:20 -0700
Re: Pointers, constant values supercat@casperkitty.com - 2015-10-17 13:59 -0700
Page 3 of 4 — ← Prev page 1 2 [3] 4 Next page →
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-10-19 11:51 +0100 |
| Message-ID | <n02hqs$uif$1@dont-email.me> |
| In reply to | #73257 |
On 19/10/2015 01:45, Ben Bacarisse wrote:
> Bartc <bc@freeuk.com> writes:
>> (No-one has yet mentioned how this works in other languages. Pointers
>> and arrays being interchangeable must surely be only another C thing.)
>
> It's very neat in Go:
>
> func amax(data []int) int {
> if l := len(data); l > 1 {
> return max(amax(data[:l/2]), amax(data[l/2:]));
> }
> return data[0]
> }
> function Amax(A: IntArray) return Integer is
> return Integer'Max(Amax(A(A'First .. A'First + L/2 - 1)),
So, they are both dealing with arrays or slices as parameters and within
the function. Neither uses raw pointers and offsets into array elements
in the user code (although no doubt that goes on internally).
Why then shouldn't I try to do the same in C? The whole point of the
sub-thread is that C has some of that capability, even if you wouldn't
normally use it because the code is also more unwieldy (not a problem
for generated code).
> Go has a slice type which represents and sized and offset index into an
> existing array. It's what C's arrays probably should have been.
I understand that Go's slices are somewhat more elaborate than arrays
and would have extra overhead (and there's a GC to help out too). That
might be OK if there are also pointers and offsets but they /need to be
distinct from arrays/!
C can also have slices via the use of functions or macros to work with
them, but you'd need functions to index them too, so it would be very
clunky.
> (Every time I write Go I am sad that it was not designed sooner. We
> might all be writing clearer code if it had been.)
(One observation on the A[n:] and A[:n] syntax: I used that in a recent
language, but found it really unintuitive. I replaced it with left(A,n)
and right(A,n). You get a hint of why, here: A[n:] is the right part of
the array, not the left! It's not so bad with full specified slice of
A[m:n])
>> I never use const (why not would be another thread). My code was a
>> self-contained program and it worked fine without it.
>
> But any claim to know what the proper type to use must apply to C as a
> whole. If all you meant is that "it works for me and the kind of C I
> write" then I doubt I'd have taken the bait! Pointers to array types
> have const issues, and these should be part of a discussion of which
> wrong type us best to use for passing arrays around.
Where's the 'const' equivalent in those examples above from other languages?
--
Bartc
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-10-19 12:55 +0100 |
| Message-ID | <871tcrkr8i.fsf@bsb.me.uk> |
| In reply to | #73275 |
Bartc <bc@freeuk.com> writes:
> On 19/10/2015 01:45, Ben Bacarisse wrote:
>> Bartc <bc@freeuk.com> writes:
>
>>> (No-one has yet mentioned how this works in other languages. Pointers
>>> and arrays being interchangeable must surely be only another C thing.)
>>
>> It's very neat in Go:
>>
>> func amax(data []int) int {
>> if l := len(data); l > 1 {
>> return max(amax(data[:l/2]), amax(data[l/2:]));
>> }
>> return data[0]
>> }
>
>> function Amax(A: IntArray) return Integer is
>> return Integer'Max(Amax(A(A'First .. A'First + L/2 - 1)),
>
> So, they are both dealing with arrays or slices as parameters and
> within the function. Neither uses raw pointers and offsets into array
> elements in the user code (although no doubt that goes on internally).
Yes.
> Why then shouldn't I try to do the same in C? The whole point of the
> sub-thread is that C has some of that capability, even if you wouldn't
> normally use it because the code is also more unwieldy (not a problem
> for generated code).
You can't pass an array or a slice in C so you have to pick some other
type. I don't think there is any point in re-hashing the arguments
about which type is the best one to use. Anyone not already convinced
by your example won't budge now.
<snip>
> (One observation on the A[n:] and A[:n] syntax: I used that in a
> recent language, but found it really unintuitive. I replaced it with
> left(A,n) and right(A,n). You get a hint of why, here: A[n:] is the
> right part of the array, not the left!
I don't find A[n:] and A[:n] unclear but I am not a fan of debates about
the details of syntax. I will, however, note something abut your
preferred names. Some people are left and right "blind" -- the words
have almost no meaning to them (other than being complimentary) unless
they stop and think about which is which. Such people would not care if
data[l/2:] is the left or the right part. What they (and indeed
everyone) really cares about is what *indexes* are included, so I might
choose first(n, data) and last(n, data) rather than left and right.
> It's not so bad with full specified slice of A[m:n])
FIW, Go's full slice has three parts where the third gives the capacity.
>>> I never use const (why not would be another thread). My code was a
>>> self-contained program and it worked fine without it.
>>
>> But any claim to know what the proper type to use must apply to C as a
>> whole. If all you meant is that "it works for me and the kind of C I
>> write" then I doubt I'd have taken the bait! Pointers to array types
>> have const issues, and these should be part of a discussion of which
>> wrong type us best to use for passing arrays around.
>
> Where's the 'const' equivalent in those examples above from other
> languages?
The translations given are, as far as I know, as close as the languages
in question can get. The Ada parameter is, by default, "in" only and Go
has no way to mark as slice as read-only.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-10-19 13:51 +0100 |
| Message-ID | <n02osd$ov4$1@dont-email.me> |
| In reply to | #73278 |
On 19/10/2015 12:55, Ben Bacarisse wrote: > Bartc <bc@freeuk.com> writes: >> Why then shouldn't I try to do the same in C? > You can't pass an array or a slice in C so you have to pick some other > type. But few languages are actually going to pass arrays by value. It is generally understood that there will be pointers and references involved. C, being lower level, has to specify those explicitly. You /want/ to pass a pointer-to-array, it's not second-best to passing a value-array. And you want to keep the pointer-to-array at the other end. C has the data-types to express a pointer-to-array, but it doesn't make it easy to use them. (C does however automatically convert an actual array, to a pointer of sorts. But this seems part of its attempt to almost airbrush value-arrays out of the language, 1984-style: If A is declared T A[n], then 'A' gets decomposed to a T* type. if a function parameter is T[], then it's changed to T*. If A is a pointer-to-array T(*)[10], then you can't use *A (ie. T[10]) in an expression.) >> Where's the 'const' equivalent in those examples above from other >> languages? > > The translations given are, as far as I know, as close as the languages > in question can get. The Ada parameter is, by default, "in" only and Go > has no way to mark as slice as read-only. Those are the kinds of approaches to 'const' that I like! C's use of const is messy, often misunderstood, can be used obsessively to clutter up the code (sometimes it's just a sea of consts), and can give a false sense of security. -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2015-10-19 06:02 -0700 |
| Message-ID | <daccaff3-e65b-42fa-811b-d2f5cb4b455c@googlegroups.com> |
| In reply to | #73285 |
On Monday, October 19, 2015 at 1:51:35 PM UTC+1, Bart wrote: > On 19/10/2015 12:55, Ben Bacarisse wrote: > > Those are the kinds of approaches to 'const' that I like! C's use of > const is messy, often misunderstood, can be used obsessively to clutter > up the code (sometimes it's just a sea of consts), and can give a false > sense of security. > I'm not totally anti-const. But it seems to me that it's there largely because it's something the compiler can do easily, rather than because it catches many bugs that are likely to slip through. You can easily enough swap source and destination buffers, but, firstly, const will catch only a subset of those errors, when the buffer passed in as destination is also const in caller, and secondly, it's not the sort of bug that's likely to live long. Usually that bug will come out on the first test. Then you've also got the interface problem. If I declare an opaque "Employee" structure, I'll also provide a "getSalary" method. Likely it just returns a field. But if that's the case, my design isn't really very good, it would make more sense to simply export the field. However maybe I've put in a security feature. Each time the employee's salary is queried, I increment a counter. Now I can maybe tell if some dishonest calling programmer is making a suspicious pattern of queries. That would be a good use of abstraction. But it means that it's none of caller's business whether getSalary() takes a const * or a plain Employee *.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-10-19 07:02 -0700 |
| Message-ID | <c945501e-8012-4bd1-a220-7b9d9393d244@googlegroups.com> |
| In reply to | #73287 |
On Monday, October 19, 2015 at 8:02:35 AM UTC-5, Malcolm McLean wrote: > I'm not totally anti-const. > > But it seems to me that it's there largely because it's something the compiler > can do easily, rather than because it catches many bugs that are likely > to slip through. You can easily enough swap source and destination buffers, > but, firstly, const will catch only a subset of those errors, when the buffer > passed in as destination is also const in caller, and secondly, it's not the sort of > bug that's likely to live long. Usually that bug will come out on the first test. There are two approaches for semantically copying and manipulate data: 1. Anyone who wants a copy of the data must make their own copy, which they may then manipulate as they see fit. 2. Entities hold shared references to data that nobody is allowed to change; an entity that wants to hold a record that differs from the one it currently holds must create or procure a record that differs from the existing one in the desired fashion. Using "const" isn't perfect, but it can nonetheless be helpful in maintaining such distinctions.
[toc] | [prev] | [next] | [standalone]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-10-19 15:39 +0100 |
| Message-ID | <n02v7f$iqe$1@dont-email.me> |
| In reply to | #73294 |
On 19/10/2015 15:02, supercat@casperkitty.com wrote: > On Monday, October 19, 2015 at 8:02:35 AM UTC-5, Malcolm McLean wrote: >> I'm not totally anti-const. >> >> But it seems to me that it's there largely because it's something the compiler >> can do easily, rather than because it catches many bugs that are likely >> to slip through. You can easily enough swap source and destination buffers, >> but, firstly, const will catch only a subset of those errors, when the buffer >> passed in as destination is also const in caller, and secondly, it's not the sort of >> bug that's likely to live long. Usually that bug will come out on the first test. > > There are two approaches for semantically copying and manipulate data: > > 1. Anyone who wants a copy of the data must make their own copy, which they > may then manipulate as they see fit. > > 2. Entities hold shared references to data that nobody is allowed to change; > an entity that wants to hold a record that differs from the one it > currently holds must create or procure a record that differs from the > existing one in the desired fashion. > > Using "const" isn't perfect, but it can nonetheless be helpful in > maintaining such distinctions. This is all part of a much bigger problem with memory management in C. 'const' would address a small part of that, and only for things that can be determined at compile-time. But it also doesn't work. If you have a tree made up of node structs that contain pointers, and you pass a const struct pointer to a routine, that doesn't stop that routine from modifying the tree via those pointers. You would have to make those pointers const too, which would make it difficult for /any/ routine to modify the tree or to build it in the first place! Or you can of course just pass a const struct pointer to a function and believe it is going to be fully protected. (Actually I had trouble applying 'const' to a struct member to stop it from being written to via the pointer. It was only after adding the *third* const here that it did what I wanted: const struct _node const * const ptr; I can't be the only one confused as hell by all these consts all over the place and might they actually mean.) -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-10-19 08:54 -0700 |
| Message-ID | <b610b85d-72d4-48ee-ad82-5d6b1b40d72f@googlegroups.com> |
| In reply to | #73296 |
On Monday, October 19, 2015 at 9:39:54 AM UTC-5, Bart wrote:
> This is all part of a much bigger problem with memory management in C.
> 'const' would address a small part of that, and only for things that can
> be determined at compile-time.
It is by no means perfect, but it can be helpful for things that are designed
from the ground up around const-correctness. Unfortunately, it is difficult
to retro-fit const-correctness into existing code, and prior to the advent of
templates there were certain places where perfect const-correctness was
impractical in any case, so the only form of "const" offered by C++ is weak
and can be overridden.
Despite that, a compiler can make some optimizations on things that are
"const" which are not possible with non-const objects; I'm not positive
exactly what optimizations are allowed under C++, but I believe it's possible
for an object to have both a "const" and "non-const" copy constructor, such
that if "fnord" is optimized for such usage...
fnord f1 = get_fnord();
f2 = f1;
const f3=f1;
const f4=f3;
const f5=f3;
f6 = f1;
would end up creating six fnord objects using four backing stores, since
f3, f4, and f5 could all use the same one. Indeed, if fnord keeps a
reference to the sharable backing store it created, if any, since the last
time it was modified, in addition to keeping its current backing store,
the same result could even be achieved with:
fnord f1 = get_fnord();
f2 = f1;
const f3=f1;
const f4=f1;
const f5=f1;
f6 = f1;
For some kinds of code that can be a pretty big win.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2015-10-19 09:14 -0700 |
| Message-ID | <11f165b4-d649-4318-a360-46dbc52d3aa9@googlegroups.com> |
| In reply to | #73305 |
On Monday, October 19, 2015 at 4:54:44 PM UTC+1, supe...@casperkitty.com wrote: > > Despite that, a compiler can make some optimizations on things that are > "const" which are not possible with non-const objects; I'm not positive > exactly what optimizations are allowed under C++, but I believe it's possible > for an object to have both a "const" and "non-const" copy constructor, such > that if "fnord" is optimized for such usage... > A C++ copy constructor is written MyObject::MyObject(const MyObject &src); It can't access any non-const methods of the source, it can't change its state. I'm not quite sure what would happen if you tried to define both a copy constructor and a similar constructor taking a non-const. (That's one of the problems with C++, you can create extremely confusing behaviour in just a few lines). But I think that basically you destroy the standard template library's object management scheme, and the whole thing goes horribly wrong.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-10-19 10:21 -0700 |
| Message-ID | <701ed2e3-26a4-41f9-8018-8df49fce0972@googlegroups.com> |
| In reply to | #73308 |
On Monday, October 19, 2015 at 11:14:37 AM UTC-5, Malcolm McLean wrote: > On Monday, October 19, 2015 at 4:54:44 PM UTC+1, supercat wrote: > > ... I believe it's possible > > for an object to have both a "const" and "non-const" copy constructor > A C++ copy constructor is written > > MyObject::MyObject(const MyObject &src); > > It can't access any non-const methods of the source, it can't change its state. You're right about copy constructors, but I remember there were new features added dealing with "const &" and also some double-ampersand thingie. Perhaps it was overloads of the assignment operator or something?
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2015-10-19 12:57 -0700 |
| Message-ID | <c435744b-7e86-4599-a2f0-98b44c8066cd@googlegroups.com> |
| In reply to | #73313 |
On Monday, October 19, 2015 at 6:21:37 PM UTC+1, supe...@casperkitty.com wrote: > > You're right about copy constructors, but I remember there were > new features added dealing with "const &" and also some > double-ampersand thingie. > Perhaps it was overloads of the assignment operator or something? > The double ampersand thingie is the "move constructor". Essentially, I've got char * asciiz string. I want to copy it to the return address, then return from my function. The original string will then be deleted. Now obviously I can strdup the string. That will work. But it's rather inefficient. It would be far better to copy the pointer to the object that receives the return, set the original to NULL, then do a no-op free as it goes out of scope. The move constructor allows you to do that. Essentially it's "swap", but it's a bit less confusing, as "swap" also has plain meaning algorithmic uses. You take the resources from the source, set source to a valid but null object state, then 99 times out of 100, source goes out of scope and is never again used. The irony is that in C the move constructor is just OBJECT *dest = src; src = 0;
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2015-10-19 21:20 +0000 |
| Message-ID | <n03mrg$2ji$1@speranza.aioe.org> |
| In reply to | #73285 |
Bartc <bc@freeuk.com> wrote:
(snip)
> But few languages are actually going to pass arrays by value. It is
> generally understood that there will be pointers and
> references involved.
Well, actually you can pass arrays by value in C if you put them
inside a struct.
> C, being lower level, has to specify those explicitly. You /want/ to
> pass a pointer-to-array, it's not second-best to passing a value-array.
> And you want to keep the pointer-to-array at the other end. C has the
> data-types to express a pointer-to-array, but it doesn't make it easy to
> use them.
I haven't looked at any actual implementation. As far as I know,
following the "as-if" rule, an implementation could pass an address
or pointer if the callee made a local copy and didn't copy back.
Note that this might cause some C program to fail, that make
assumptions on how pass by value works:
printf("%08x%08x", 1.234);
don't do that.
-- glen
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-10-20 20:50 -0700 |
| Message-ID | <d03b26ed-8638-452a-9cb3-18d96ba105f6@googlegroups.com> |
| In reply to | #73342 |
On Monday, October 19, 2015 at 4:20:59 PM UTC-5, glen herrmannsfeldt wrote: > I haven't looked at any actual implementation. As far as I know, > following the "as-if" rule, an implementation could pass an address > or pointer if the callee made a local copy and didn't copy back. That's pretty commonly done since it moves the structure-copying code from the call site to the called function, and since there are usually fewer called functions than call sites that's often a win. An optimization which would seem fairly straightforward but which I've not seen offered in any ABI would be have every function which takes one or more structures by value have multiple entry points which callers would select based upon which structures the called function would be required to copy always (because the caller knows they might be aliased), only if it modifies them (because the caller will never need them again), or never (they aren't aliased, and the caller will never need them again). The scenarios where a structure isn't aliased and either the caller will never need it again or the recipient isn't going to modify it are pretty common, but and shouldn't require that the structure be copied, but I've not heard of any tool system which tries to optimize for that without going into full-fledged link-time optimization.
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2015-10-21 04:58 +0000 |
| Message-ID | <n0761f$hqc$1@speranza.aioe.org> |
| In reply to | #73443 |
supercat@casperkitty.com wrote: > On Monday, October 19, 2015 at 4:20:59 PM UTC-5, glen herrmannsfeldt wrote: >> I haven't looked at any actual implementation. As far as I know, >> following the "as-if" rule, an implementation could pass an address >> or pointer if the callee made a local copy and didn't copy back. > That's pretty commonly done since it moves the structure-copying code from > the call site to the called function, and since there are usually fewer > called functions than call sites that's often a win. Well, I meant it more than just for structures, but them, too. > An optimization which would seem fairly straightforward but which I've not > seen offered in any ABI would be have every function which takes one or > more structures by value have multiple entry points which callers would > select based upon which structures the called function would be required > to copy always (because the caller knows they might be aliased), > only if it modifies them (because the caller will never need > them again), or never (they aren't aliased, and the caller will > never need them again). I don't know about others, but I don't think I have ever used pass structs by value. I suspect it might get used for small structs, but it is probably better not to use for large ones. > The scenarios where a structure isn't aliased and either the > caller will never need it again or the recipient isn't going > to modify it are pretty common, but and shouldn't require > that the structure be copied, but I've not heard of any tool > system which tries to optimize for that without going into > full-fledged link-time optimization. -- glen
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-10-19 08:40 -0700 |
| Message-ID | <lnpp0azx1o.fsf@kst-u.example.com> |
| In reply to | #73257 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
[...]
> And in Ada (though I'm less sure if this is really idiomatic):
>
> function Amax(A: IntArray) return Integer is
> L: Natural := A'Last - A'First + 1;
> begin
> if L > 1 then
> return Integer'Max(Amax(A(A'First .. A'First + L/2 - 1)),
> Amax(A(A'First + L/2 .. A'Last)));
> else
> return A(A'First);
> end if;
> end amax;
You can drop L and use A'Length.
The function will die (raise the Constraint_Error exception)
if you give it an empty array, which is perfectly legal in Ada.
Perhaps that's sensible thing for it to do, but it's probably
cleaner to do it explicitly with a `raise` statement.
The point is that Ada supports "array slices". Ada array indexing is
not defined in terms of pointer arithmetic. Arrays can be passed as
parameters, and the A'First, A'Last, and A'Length attributes work on
parameters the same way as on any other array objects. Given an array A,
the slice A(X..Y) is an array object consisting of the elements of A
from indices X to Y, inclusive.
[...]
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-10-19 20:17 +0100 |
| Message-ID | <8737x6zn02.fsf@bsb.me.uk> |
| In reply to | #73302 |
Keith Thompson <kst-u@mib.org> writes: > Ben Bacarisse <ben.usenet@bsb.me.uk> writes: > [...] >> And in Ada (though I'm less sure if this is really idiomatic): >> >> function Amax(A: IntArray) return Integer is >> L: Natural := A'Last - A'First + 1; >> begin <snip> >> end amax; > > You can drop L and use A'Length. Thanks. I was sure there'd be something. <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-10-17 16:44 -0700 |
| Message-ID | <6490f27e-dd45-4b1c-aabf-8e10d044ddc2@googlegroups.com> |
| In reply to | #73157 |
On Saturday, October 17, 2015 at 4:42:51 PM UTC-5, Bart wrote:
> Because to do it my way (ie. 'properly') requires an explicit
> dereference of the array (to index it in the callee). And because '*' is
> a prefix op, it also needs extra parentheses. So it is a PITA (to answer
> one of your other comments).
I think that's minor compared to the fact that before C99 one could only
use an array type (rather than a pointer) if the size of the array was
fixed, which in many cases it won't be, and C99 variable-length arrays
add problems of their own.
For example, in some kinds of code there is a very common idiom where
a function which may or may not need to be given an array by its caller
accepts a arguments for the base pointer and size, but promises to ignore
the passed-in pointer if the size is zero. While the declaration:
void processCommand(int command, char (*dat)[size], int size);
would be valid in C99, a compiler would be entitled to assume that the
function could never be invoked when "size" has a value of zero--an
assumption which would contradict what might well be the most common usage
case.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-10-18 11:52 +0100 |
| Message-ID | <876124o3ct.fsf@bsb.me.uk> |
| In reply to | #73175 |
supercat@casperkitty.com writes: <snip> > For example, in some kinds of code there is a very common idiom where > a function which may or may not need to be given an array by its caller > accepts a arguments for the base pointer and size, but promises to ignore > the passed-in pointer if the size is zero. While the declaration: > > void processCommand(int command, char (*dat)[size], int size); The size parameter must come before the parameter that refers to it. > would be valid in C99, a compiler would be entitled to assume that the > function could never be invoked when "size" has a value of zero --an > assumption which would contradict what might well be the most common usage > case. What use-case do you have in mind? The most common use I've seen of this pattern is in numerical work for passing a 2D arrays with a run-time "stride". In those cases, pointers to zero-length arrays are not common (nor are they particularly useful degenerate cases). -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2015-10-18 05:15 -0700 |
| Message-ID | <3e57e99e-ea52-40b1-b491-bed7ab4823a5@googlegroups.com> |
| In reply to | #73196 |
On Sunday, October 18, 2015 at 11:53:03 AM UTC+1, Ben Bacarisse wrote: > supercat@casperkitty.com writes: > <snip> > > For example, in some kinds of code there is a very common idiom where > > a function which may or may not need to be given an array by its caller > > accepts a arguments for the base pointer and size, but promises to ignore > > the passed-in pointer if the size is zero. While the declaration: > > > > void processCommand(int command, char (*dat)[size], int size); > > The size parameter must come before the parameter that refers to it. > > > would be valid in C99, a compiler would be entitled to assume that the > > function could never be invoked when "size" has a value of zero --an > > assumption which would contradict what might well be the most common usage > > case. > > What use-case do you have in mind? The most common use I've seen of > this pattern is in numerical work for passing a 2D arrays with a > run-time "stride". In those cases, pointers to zero-length arrays are > not common (nor are they particularly useful degenerate cases). > In the case given, the function is obviously some sort of message handler, probably designed to be passed in by indirection and used as a callback. To allow for a fast switch on the message type, it's an integer, and to allow for extension, the caller can attach arbitrary data in the form of a string. As it happens, I was designing exactly such a system literally yesterday. In my case, most of the messages will be commands like "zoom in", "pan by fixed amount", "copy selection to clipboard". That's because mostly they originate as mouse clicks on buttons in the UI. But a few have values, "set stroke width" will obviously need to pass a setting. And of course the UI framework supports entering strings, though users tend to dislike doing that. So the string parameter won't be used much, but it's there for when needed.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-10-18 21:54 +0100 |
| Message-ID | <8737x7nbht.fsf@bsb.me.uk> |
| In reply to | #73202 |
Malcolm McLean <malcolm.mclean5@btinternet.com> writes: > On Sunday, October 18, 2015 at 11:53:03 AM UTC+1, Ben Bacarisse wrote: >> supercat@casperkitty.com writes: >> <snip> >> > For example, in some kinds of code there is a very common idiom where >> > a function which may or may not need to be given an array by its caller >> > accepts a arguments for the base pointer and size, but promises to ignore >> > the passed-in pointer if the size is zero. While the declaration: >> > >> > void processCommand(int command, char (*dat)[size], int size); >> >> The size parameter must come before the parameter that refers to it. >> >> > would be valid in C99, a compiler would be entitled to assume that the >> > function could never be invoked when "size" has a value of zero --an >> > assumption which would contradict what might well be the most common usage >> > case. >> >> What use-case do you have in mind? The most common use I've seen of >> this pattern is in numerical work for passing a 2D arrays with a >> run-time "stride". In those cases, pointers to zero-length arrays are >> not common (nor are they particularly useful degenerate cases). >> > In the case given, the function is obviously some sort of message > handler, probably designed to be passed in by indirection and used as > a callback. Not, it seems, according to its author. But if you've got a use-case for it, that will help... > To allow for a fast switch on the message type, it's an integer, and to allow for > extension, the caller can attach arbitrary data in the form of a > string. But what about the parts that matter -- the pointer to array type and the variable length array type haveing size zero. How does your context make that (a) a reasonable API choice and (b) a most common usage case? > As it happens, > I was designing exactly such a system literally yesterday. And you wanted to use VLA parameters, but you found that the size being zero was a common case so you could not do it that way? If not, what is the relevance to my question? <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2015-10-18 16:09 -0700 |
| Message-ID | <39fc02f9-b84d-4252-a195-00de04531ed0@googlegroups.com> |
| In reply to | #73234 |
On Sunday, October 18, 2015 at 9:54:46 PM UTC+1, Ben Bacarisse wrote: > Malcolm McLean <malcolm.mclean5@btinternet.com> writes: > > > As it happens, > > I was designing exactly such a system literally yesterday. > > And you wanted to use VLA parameters, but you found that the size being > zero was a common case so you could not do it that way? If not, what is > the relevance to my question? > I haven't finalised it. I'll do it tomorrow (yikes, today). But I'm think of something along the line of std::string callback(int command, std::string const &message) C+ doesn't allow for null references. So you'd pass in the empty string. Obviously a C interface would have a smidgen more micro- efficiency. I might go for a boost::optional. Is there a difference between no string of sausages and a string of no sausages?
[toc] | [prev] | [next] | [standalone]
Page 3 of 4 — ← Prev page 1 2 [3] 4 Next page →
Back to top | Article view | comp.lang.c
csiph-web