Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #73016 > unrolled thread

Pointers, constant values

Started byAlla _ <modelling.data@gmail.com>
First post2015-10-16 00:49 -0700
Last post2015-10-17 13:59 -0700
Articles 20 on this page of 77 — 14 participants

Back to article view | Back to comp.lang.c


Contents

  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 →


#73275

FromBartc <bc@freeuk.com>
Date2015-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]


#73278

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-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]


#73285

FromBartc <bc@freeuk.com>
Date2015-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]


#73287

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2015-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]


#73294

Fromsupercat@casperkitty.com
Date2015-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]


#73296

FromBartc <bc@freeuk.com>
Date2015-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]


#73305

Fromsupercat@casperkitty.com
Date2015-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]


#73308

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2015-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]


#73313

Fromsupercat@casperkitty.com
Date2015-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]


#73330

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2015-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]


#73342

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2015-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]


#73443

Fromsupercat@casperkitty.com
Date2015-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]


#73444

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2015-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]


#73302

FromKeith Thompson <kst-u@mib.org>
Date2015-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]


#73328

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-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]


#73175

Fromsupercat@casperkitty.com
Date2015-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]


#73196

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-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]


#73202

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2015-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]


#73234

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-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]


#73252

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2015-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