Monday, August 9, 2021

Digest for comp.lang.c++@googlegroups.com - 8 updates in 1 topic

MrSpud_ifhov@nldls6_1kg3nl2qnwv.biz: Aug 09 08:19AM

On Sun, 8 Aug 2021 09:23:46 -0400
>behavior is undefined." (C2011 6.5.6p9).
 
>If the result of a pointer subtraction were always guaranteed to be
>representable in ptrdiff_t, then that last sentence would be vacuous.
 
Then don't use ptrdiff_t. I suspect like most people I wasn't even aware
it existed.
 
>"These types are optional". A fully conforming implementation may have
>pointers that are too big to be representable using any supported
>integer type, and the same is true of pointer differences.
 
So long as mathematical operations can be done on the pointer types (which
is a given or they'd be no use as pointers) then they are de facto integer
types and that statement is wrong.
MrSpud_1dgrmf@dx58865qyrdw30lqllb.info: Aug 09 08:21AM

On Sun, 8 Aug 2021 15:04:52 -0000 (UTC)
>result when they point to the same array (which would be within
>the same segment). Else you get garbage (if the two pointers are
>pointing to different segments).
 
I was discussing from the POV of a proper OS, not some half baked monitor
program from the 70s. However if you can't work out how to get a valid diff
from the above then clearly your maths skills need some work.
Juha Nieminen <nospam@thanks.invalid>: Aug 09 08:53AM


> I was discussing from the POV of a proper OS, not some half baked monitor
> program from the 70s. However if you can't work out how to get a valid diff
> from the above then clearly your maths skills need some work.
 
The standard (neither the C nor the C++ standard) doesn't care what kind of
OS is running the program. And, on top of that, what I described is a
feature of the x86 architecture, not a feature of the OS. If the OS, any OS,
runs in 16-bit real mode, it will have to deal with that problem somehow.
 
The fact is that the standard only supports calculating the difference
between two pointers if they point to the same object or the same array
(or one past the end of the array). In any other situation the behavior
is undefined. I gave a practical example of where this could cause an
issue if you ignore the standard.
Juha Nieminen <nospam@thanks.invalid>: Aug 09 08:55AM

> So long as mathematical operations can be done on the pointer types (which
> is a given or they'd be no use as pointers) then they are de facto integer
> types and that statement is wrong.
 
You are assuming that a pointer is internally not only an integer, but a
single integer. That's not necessarily the case.
James Kuyper <jameskuyper@alumni.caltech.edu>: Aug 09 12:16PM -0400

> On Sun, 8 Aug 2021 09:23:46 -0400
> James Kuyper <jameskuyper@alumni.caltech.edu> wrote:
...
>> representable in ptrdiff_t, then that last sentence would be vacuous.
 
> Then don't use ptrdiff_t. I suspect like most people I wasn't even aware
> it existed.
 
I hope you're wrong about that - it's a fairly basic aspect of C, like
[u]intptr_t or size_t. But my degree was in Physics, not CS, so I don't
have any idea how bad the average CS major's education might have been.
 
If you never need to store the result of pointer subtractions, there's
no need to use ptrdiff_t. If you're calculating the difference between
pointers, and know enough about the calculation to at least roughly
estimate the minimum and maximum possible values that might result, and
know that both the minimum and maximum differences are small enough to
be stored in an integer of a given type, you can use an integer of that
type to store the result. ptrdiff_t is needed only if you have no other
information to go on about the size of a pointer difference that you
need to store - and if ptrdiff_t cannot represent such a value, it's
likely to be the case that there is no integer type supported by that
implementation that can. If there were such a type, it would have been
used as ptrdiff_t.
 
 
> So long as mathematical operations can be done on the pointer types (which
> is a given or they'd be no use as pointers) then they are de facto integer
> types and that statement is wrong.
 
Yes, but when these issues come into play, the relevant mathematical
operations cannot be done on pointer types. The result of a pointer
subtraction has the type ptrdiff_t, and if an actual difference results
in a value that cannot be represented in that type, the behavior is
undefined, and on real-life implementations where this can happen, the
likely result will be the same as trying to calculate a value by any
other means that is too large to be represented in that type. That
wording is deliberately vague, because the "likely result" I'm referring
to can be (and probably is) different for different implementations.
Possible results include rolling over large positive differences to
become large negative ones and vice-versa, or saturation arithmetic, or
the raising of a signal. How many cases do you know of where any one of
those three results would be acceptable?
 
You're used to systems where ptrdiff_t and [u]intptr_t can be defined by
the implementation to be types that are big enough to store any pointer
difference, and any suitably-converted pointer value, respectively. So
am I. But the standard was written by a committee that, collectively,
had far broader experience than either you or I, and that wording was
added because the committee was well aware of systems for which that was
not the case. Unless you know which systems the committee thought had
that issue, and can authoritatively tell them that they were wrong about
those systems, your beliefs to the contrary don't count for much.
MrSpud_HG@_0b772d8ha3yjo0xb.edu: Aug 09 04:23PM

On Mon, 9 Aug 2021 12:16:46 -0400
 
>I hope you're wrong about that - it's a fairly basic aspect of C, like
>[u]intptr_t or size_t. But my degree was in Physics, not CS, so I don't
>have any idea how bad the average CS major's education might have been.
 
Ooo look at you, supercilious and patronising all in one go. Well done,have
a scooby snack.
 
>If you never need to store the result of pointer subtractions, there's
>no need to use ptrdiff_t. If you're calculating the difference between
>pointers, and know enough about the calculation to at least roughly
 
Any parser beyond the most basic needs to do pointer arithmetic and I've
written a LOT of them.
 
>likely to be the case that there is no integer type supported by that
>implementation that can. If there were such a type, it would have been
>used as ptrdiff_t.
 
I should have clarified in my origional post that I was refering to programming
in grown up OS's on grown up CPUs. Not on DOS with 1970s x86 segmentation.
 
>> types and that statement is wrong.
 
>Yes, but when these issues come into play, the relevant mathematical
>operations cannot be done on pointer types. The result of a pointer
 
They can in *nix which is good enough for me.
"Alf P. Steinbach" <alf.p.steinbach@gmail.com>: Aug 09 07:53PM +0200

On 9 Aug 2021 10:53, Juha Nieminen wrote:
> (or one past the end of the array). In any other situation the behavior
> is undefined. I gave a practical example of where this could cause an
> issue if you ignore the standard.
 
True, but. `std::less` & family impose a total order on pointers of the
same type, where for directly comparable pointers (i.e. within the same
array or single-object-as-size-one-array) that order is the same as the
`<` order. That implies that internally these functions compute some
absolute representation of pointers, mapping segment selectors to lower
level addresses as necessary.
 
I would guess that an argument can be made that in practice you will
always get that absolute representation by converting to `void*` and
then to `uintptr_t`.
 
However, as far as I know that's not guaranteed or formally implied by
the standard. It would have been nice if the standard /had/ exposed the
internal workings here, just as it would have been nice if the standard
/had/ exposed e.g. the internal non-throwing string representation used
in exceptions. Alas.
 
 
- Alf
Vir Campestris <vir.campestris@invalid.invalid>: Aug 09 09:50PM +0100

> I should have clarified in my origional post that I was refering to programming
> in grown up OS's on grown up CPUs. Not on DOS with 1970s x86 segmentation.
 
You're probably not aware then that the CD DS ES SS registers from that
1970s x86 are still alive and well under the hood, even though they
often point to the same address space, and the offsets are 32 or 64 bit.
 
What bothers me about ptr_diff_t is the size. The difference between two
32-bit pointers is plus or minus 4GB. Which needs a 33 bit value :(
 
It's the same with 64 bit.
 
As it happens it's never been a practical problem as I've never had a 32
bit system with more than 2GB RAM, and don't expect the 64 bit limit to
be a problem any time soon.
 
Andy
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: