Tuesday, April 2, 2019

Digest for comp.lang.c++@googlegroups.com - 21 updates in 4 topics

Cholo Lennon <chololennon@hotmail.com>: Apr 02 03:47AM -0300

On 3/30/19 6:27 PM, Mr Flibble wrote:
> My universal compiler will cause a technological singularity.
 
> https://neos.dev
 
It seems that you have some kind of "competition" ;-) see this:
 
https://www.graalvm.org/
 
I've learned about that from the following post:
 
https://www.theregister.co.uk/2019/03/29/mozilla_wasi_spec/
 
 
Regards
 
--
Cholo Lennon
Bs.As.
ARG
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Apr 02 03:38PM +0100

On 02/04/2019 07:47, Cholo Lennon wrote:
 
> https://www.graalvm.org/
 
> I've learned about that from the following post:
 
> https://www.theregister.co.uk/2019/03/29/mozilla_wasi_spec/
 
At first glance it does appear to be competition for neos however I don't
have the time to research it more closely to see what the actual technical
differences are.
 
/Flibble
 
--
"You won't burn in hell. But be nice anyway." – Ricky Gervais
 
"I see Atheists are fighting and killing each other again, over who
doesn't believe in any God the most. Oh, no..wait.. that never happens." –
Ricky Gervais
 
"Suppose it's all true, and you walk up to the pearly gates, and are
confronted by God," Bryne asked on his show The Meaning of Life. "What
will Stephen Fry say to him, her, or it?"
"I'd say, bone cancer in children? What's that about?" Fry replied.
"How dare you? How dare you create a world to which there is such misery
that is not our fault. It's not right, it's utterly, utterly evil."
"Why should I respect a capricious, mean-minded, stupid God who creates a
world that is so full of injustice and pain. That's what I would say."
"Chris M. Thomasson" <invalid_chris_thomasson_invalid@invalid.com>: Apr 02 01:47PM -0700

On 4/1/2019 11:47 PM, Cholo Lennon wrote:
 
> https://www.graalvm.org/
 
> I've learned about that from the following post:
 
> https://www.theregister.co.uk/2019/03/29/mozilla_wasi_spec/
 
Interesting. Thank you for the heads up.
Bonita Montero <Bonita.Montero@gmail.com>: Apr 02 08:12AM +0200

Just asked the same question on Stack Overflow.
 
This...>     // doesn't work>     // template<typename U>>     //
friend class C<U>;... should be this ...
template<typename U>
friend class C;
Thiago Adams <thiago.adams@gmail.com>: Apr 02 10:50AM -0700

On Tuesday, April 2, 2019 at 3:12:33 AM UTC-3, Bonita Montero wrote:
> friend class C<U>;... should be this ...
> template<typename U>
> friend class C;
 
Maybe this can help
http://www.gotw.ca/gotw/076.htm
 
Each template class is a unique type with no relationship
with the other instantiations. You are trying to declare
a friend that you know known anything about it.
 
In case you have a class for numeric types you can make
your class explicitly be friend of each possible
instantiations that you can think about. (int, long, double etc...)
 
 
template<typename T>
class C
{
public:
template<typename U>
void f123( C<U> &other )
{
other.i = 1;
}
 
private:

friend class C<float>;
friend class C<int>;
 
...etc...
 
int i;
};
Daniel <danielaparker@gmail.com>: Apr 02 11:10AM -0700

On Tuesday, April 2, 2019 at 1:50:15 PM UTC-4, Thiago Adams wrote:
 
> Maybe this can help
> http://www.gotw.ca/gotw/076.htm
 
That's old :-) Things have changed.
 
Bonita's second post has the correct answer.
 
Daniel
Thiago Adams <thiago.adams@gmail.com>: Apr 02 11:38AM -0700

On Tuesday, April 2, 2019 at 3:10:29 PM UTC-3, Daniel wrote:
 
> > Maybe this can help
> > http://www.gotw.ca/gotw/076.htm
 
> That's old :-) Things have changed.
 
I missed the answer because of formatting.
Sorry for the noise.
 
I didn't know about that.
Interesting that any instantiation of C
is friend.
 
template<typename U> friend class C;
Paavo Helde <myfirstname@osa.pri.ee>: Apr 01 09:20PM +0300

On 1.04.2019 20:51, Mr Flibble wrote:
>> memory.
 
> The standard is correct: a copy of an object has a different identity to
> the original object
 
If so, why this is not UB?
 
std::vector<std::string> v;
v.push_back("original");
auto iter = v.begin();
std::string x("copy");
v[0] = std::move(x);
std::cout << *iter;
"Öö Tiib" <ootiib@hot.ee>: Apr 02 01:49AM -0700

On Tuesday, 2 April 2019 01:18:35 UTC+3, Alf P. Steinbach wrote:
> consecutive items, no padding, in the multidimensional array.
 
> Perhaps you were not aware?
 
> Or if you were aware of that, can you give an example of the UB way?
 
Only with char pointer we may do pointer arithmetics on whole
array of arrays since it is an object and char pointer is allowed
to access consecutive bytes of an object (like you say there are
no padding). Standard has no concept of multidimensional array
and global indexing by other means in it is not defined.
 
So if we have pointer like p = &a[0][0] where a is T[M][N] then
[expr.add] (to what other things like increments, decrements
and [] refer) does explicitly tell that it is undefined behavior to
go any farther than from (p + 0) to (p + N) with it. I am not sure
why it is so but it has been as long I remember only wording of
it has changed over time a bit. Something similar is in C standard
too.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Apr 02 11:58AM +0200

On 02.04.2019 10:49, Öö Tiib wrote:
> array of arrays since it is an object and char pointer is allowed
> to access consecutive bytes of an object (like you say there are
> no padding). Standard has no concept of multidimensional array
 
It has.
 
C++17 8.3.4/3
«When several "array of" specifications are adjacent, a multidimensional
array is created; only the first of the constant expressions that
specify the bounds of the arrays may be omitted.»
 
 
> and global indexing by other means in it is not defined.
 
That sounds incorrect but it depends on what you mean by "global indexing."
 
 
> [expr.add] (to what other things like increments, decrements
> and [] refer) does explicitly tell that it is undefined behavior to
> go any farther than from (p + 0) to (p + N) with it.
 
No, it doesn't.
 
On the contrary, it gives a hard requirement that it shall work;
 
«Moreover, if the expression P points to the last element of an array
object, the expression (P)+1 points one past the last element of the
array object.»
 
And in a multidimensional array one past the last element of an inner
array, is guaranteed to be the first element of a next inner array,
except for the last inner array.
 
 
> I am not sure why it is so but it has been as long I remember only
> wording of it has changed over time a bit. Something similar is in
> C standard too.
 
It's just a sabotage meme originating with some unreasoning socially
oriented first-year students that had a Very Ungood Teacher™ (VUT™).
 
Or at least that's my theory. :)
 
 
Cheers & hth.,
 
- Alf
"Öö Tiib" <ootiib@hot.ee>: Apr 02 03:59AM -0700

On Tuesday, 2 April 2019 12:58:30 UTC+3, Alf P. Steinbach wrote:
> specify the bounds of the arrays may be omitted.»
 
> > and global indexing by other means in it is not defined.
 
> That sounds incorrect but it depends on what you mean by "global indexing."
 
I did mean indexing multidimensional arrays like unidimensional.
 
> > and [] refer) does explicitly tell that it is undefined behavior to
> > go any farther than from (p + 0) to (p + N) with it.
 
> No, it doesn't.
 
In what version? I have read it from C++98 to C++17 all the same.
 
 
> «Moreover, if the expression P points to the last element of an array
> object, the expression (P)+1 points one past the last element of the
> array object.»
 
That is exactly (p + N) what I wrote above.
 
> And in a multidimensional array one past the last element of an inner
> array, is guaranteed to be the first element of a next inner array,
> except for the last inner array.
 
There is difference between pointer arithmetic and locations of
elements of arrays in memory. Standard does not indicate that
we are free to add or subtract anything to pointer. On the contrary,
[expr.add] is more strict there. So it is true that the pointer (p + N)
is valid and is guaranteed to compare equal with pointer at first
element of next inner array (&a[1][0]) but also it is true
that (p + N + 1) is explicitly told to be undefined behavior.
 
 
> It's just a sabotage meme originating with some unreasoning socially
> oriented first-year students that had a Very Ungood Teacher™ (VUT™).
 
> Or at least that's my theory. :)
 
:D
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Apr 02 01:23PM +0200

On 02.04.2019 12:59, Öö Tiib wrote:
>> object, the expression (P)+1 points one past the last element of the
>> array object.»
 
> That is exactly (p + N) what I wrote above.
 
At least we're clear on that, that /one/ part of the standard requires
it to be well-defined.
 
Do you agree that for the abstract machine defined by the standard, the
history of how a valid pointer value was computed does not matter if
that history did not involve UB (as it cleary does not for (P)+1)?
 
 
> [expr.add] is more strict there. So it is true that the pointer (p + N)
> is valid and is guaranteed to compare equal with pointer at first
> element of next inner array (&a[1][0])
 
Yes, it's valid.
 
 
> but also it is true
> that (p + N + 1) is explicitly told to be undefined behavior.
 
Not if you require (P+2) to be equivalent to ((P+1)+1), which is well
defined.
 
To make this alleged UB have a practical effect one needs a perverse
compiler that adds checking of whether N > 1.
 
Such a compiler /can/ be implemented, and can possibly be argued to be
formally correct, because the standard does not require `+` to be
associative: the C++ version groups left to right.
 
But we can reason about the standard imposing requirements such as P+2
having to be split up in two operations (P+1)+1, and so on, that for
practical effect requires over-the-top sabotaging compiler perversity,
at the technical cost of the inefficiency of "fat pointers", and the
higher level cost of breaking a really large amount of existing code,
and introducing the notion that the history of a pointer matters.
 
Would that be reasonable or serve any engineering purpose? Nope. It's
just hogwash, an unnatural, totally impractical code-breaking
interpretation that completely disregards context and purpose.
 
 
>> oriented first-year students that had a Very Ungood Teacher™ (VUT™).
 
>> Or at least that's my theory. :)
 
> :D
 
Yes.
 
 
Cheers!,
 
- Alf
Paavo Helde <myfirstname@osa.pri.ee>: Apr 02 03:15PM +0300

On 2.04.2019 11:49, Öö Tiib wrote:
> why it is so but it has been as long I remember only wording of
> it has changed over time a bit. Something similar is in C standard
> too.
 
Just curious, is this to support something like segmented addresses in
16-bit MS-DOS in the case where the whole 2D array would not fit in the
same segment?
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Apr 02 02:46PM +0200

On 02.04.2019 14:15, Paavo Helde wrote:
 
> Just curious, is this to support something like segmented addresses in
> 16-bit MS-DOS in the case where the whole 2D array would not fit in the
> same segment?
 
It isn't and it couldn't, since you can do p+N by repeated application
of indisputably well-defined P+1.
 
It's just bollocks.
 
 
Cheers!,
 
- Alf
"Öö Tiib" <ootiib@hot.ee>: Apr 02 05:48AM -0700

On Tuesday, 2 April 2019 14:23:40 UTC+3, Alf P. Steinbach wrote:
 
> Do you agree that for the abstract machine defined by the standard, the
> history of how a valid pointer value was computed does not matter if
> that history did not involve UB (as it cleary does not for (P)+1)?
 
I believe that it is meant differently. AFAICS that (P+1) is valid
pointer value and compares equal with valid pointer value R
(pointer of first element of next array).
However dereferencing of that valid pointer (P+1) is UB
despite R can be dereferenced. And further (R+1) is valid
pointer value but (P+1)+1 (or P+2, doesn't matter) is invalid
pointer value that may or may not compare equal with (R+1).
Places like [basic.std.dynamic.safety] hint at it.
 
> defined.
 
> To make this alleged UB have a practical effect one needs a perverse
> compiler that adds checking of whether N > 1.
 
Oh, there will be likely built "perverse" processors that support such
checked pointers right away as part of dereference operations. For
lot of people that has been sort of dream to improve safety of pointers
for long time.

> at the technical cost of the inefficiency of "fat pointers", and the
> higher level cost of breaking a really large amount of existing code,
> and introducing the notion that the history of a pointer matters.
 
I wrote about it above how I think that it is meant.
 
> Would that be reasonable or serve any engineering purpose? Nope. It's
> just hogwash, an unnatural, totally impractical code-breaking
> interpretation that completely disregards context and purpose.
 
How no purpose? The buffer overflows are actually nasty issue
and beneficial to no one. It is good purpose to at least allow
architectures that make those less frequent or even impossible.
 
"Öö Tiib" <ootiib@hot.ee>: Apr 02 05:56AM -0700

On Tuesday, 2 April 2019 15:15:27 UTC+3, Paavo Helde wrote:
 
> Just curious, is this to support something like segmented addresses in
> 16-bit MS-DOS in the case where the whole 2D array would not fit in the
> same segment?
 
I trust it is about allowing traceable pointer objects described in
[basic.stc.dynamic.safety]. I don't know if any implementation
implements those.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Apr 02 03:57PM +0200

On 02.04.2019 14:48, Öö Tiib wrote:
> (pointer of first element of next array).
> However dereferencing of that valid pointer (P+1) is UB
> despite R can be dereferenced.
 
So, say you do P2 = P+1, in the case where P2 is guaranteed to compare
equal to a pointer to the first element of the next inner array.
 
Is the history, that P2 was computed as P+1, forgotten at some point?
 
Or will it be UB to dereference the stored pointer value in P2, just as
it is with the expression P+1?
 
P2 points to the first item in an array, but as I understand it you mean
that it's UB to form P2+1, and well-defined to form P2-1, because it
/came from/ an earlier part; is that reasonable, do you think?
 
Or can your argument be applied to P2 also, that no arithmetic
whatsoever can be done with it?
 
Can't go forward because it came from previous inner array. Can't go
backward because it's at the start of an array. Immobile pointer, yes?
 
 
> checked pointers right away as part of dereference operations. For
> lot of people that has been sort of dream to improve safety of pointers
> for long time.
 
But think about it.
 
The nice checking processor can't prevent me from traversing the array
one step at a time, which is indisputably well-defined.
 
It can only prevent me from /efficiently/ going in strides across the
array, as is often done in image processing.
 
Well, okay, so then we also need a hardware image processor to help out
with that particular area.
 
All this extra hardware and fat pointer overhead is surely what the C++
committee had in mind, a small cost indeed to pay for detecting some
programmers' bad practices that give buffer overruns.
 
 
>> higher level cost of breaking a really large amount of existing code,
>> and introducing the notion that the history of a pointer matters.
 
> I wrote about it above how I think that it is meant.
 
No, you didn't.
 
I've seen no suggestion of a rationale.
 
It's just a totally impractical nonsense interpretation.
 
 
 
> How no purpose? The buffer overflows are actually nasty issue
> and beneficial to no one. It is good purpose to at least allow
> architectures that make those less frequent or even impossible.
 
There are no buffer overflows in code to iterate through a
multidimensional array.
 
The wording it appears that you focus on is for individual arrays.
 
That's a different context.
 
 
 
>>>> Or at least that's my theory. :)
 
>>> :D
 
>> Yes.
 
 
Cheers!,
 
- Alf
"Öö Tiib" <ootiib@hot.ee>: Apr 02 07:57AM -0700

On Tuesday, 2 April 2019 16:57:14 UTC+3, Alf P. Steinbach wrote:
 
> Is the history, that P2 was computed as P+1, forgotten at some point?
 
> Or will it be UB to dereference the stored pointer value in P2, just as
> it is with the expression P+1?
 
Yes, dereferencing P2 that was calculated as P+1 is UB.
It is likely not meant to be history how it was calculated but as a
state of the pointer. The pointer P2 is at one past last of its range,
while pointer to the first element of the next inner array is at start
of its range. These compare equal but P2 can't be dereferenced.

> /came from/ an earlier part; is that reasonable, do you think?
 
> Or can your argument be applied to P2 also, that no arithmetic
> whatsoever can be done with it?
 
Yes, P2-1 is valid and can be dereferenced again.
 
> Can't go forward because it came from previous inner array. Can't go
> backward because it's at the start of an array. Immobile pointer, yes?
 
No, P2 is one past last of previous inner array that compares equal to
start of next inner array. It can't be dereferenced but can be
decremented back up to start of previous inner array.
 
 
> All this extra hardware and fat pointer overhead is surely what the C++
> committee had in mind, a small cost indeed to pay for detecting some
> programmers' bad practices that give buffer overruns.
 
I trust that such wording is not in C and C++ standards because of
programmers being clumsy but because of hardware manufacturers
being toying with various fat pointer concepts for decades.
 
 
> No, you didn't.
 
> I've seen no suggestion of a rationale.
 
> It's just a totally impractical nonsense interpretation.
 
You have for some reason decided that it is nonsense
but it is unclear (to me) what is the reason.
 
> multidimensional array.
 
> The wording it appears that you focus on is for individual arrays.
 
> That's a different context.
 
Consider int arr[5][5]. Now accessing arr[0][5] is one kind of
buffer overflow and it is bad that it is equivalent to accessing
arr[1][0] on most platforms.
 
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Apr 02 05:33PM +0200

On 02.04.2019 16:57, Öö Tiib wrote:
 
> Consider int arr[5][5]. Now accessing arr[0][5] is one kind of
> buffer overflow and it is bad that it is equivalent to accessing
> arr[1][0] on most platforms.
 
Array indexing is defined in terms of pointer arithmetic; the []
operator applies to pointers, not arrays.
 
So `arr[0][5]` is by definition `*(arr[0] + 5)` which in turn is by
definition `*(*(arr + 0) + 5)` which is equivalent to `*(*arr + 5)`.
 
And `arr[1][0]` is by definition `*(arr[1] + 0)` which in turn is by
definition `*(*(arr + 5) + 0)` which is `*(*arr + 5)`.
 
On which platform are these expressions not equivalent?
 
I.e., when you say it holds on "most platforms", on which platform does
the equivalence not hold?
 
 
Cheers!,
 
- Alf
Sam <sam@email-scan.com>: Apr 01 06:04PM -0400

Chris M. Thomasson writes:
 
 
>>> The older I get the less tolerant I am of idiot trolls on usenet.
 
>> Metamucil is cheap.
 
> Jesus!
 
No, I'm not him. But that was an understandable mistake.
"Chris M. Thomasson" <invalid_chris_thomasson_invalid@invalid.com>: Apr 01 08:45PM -0700

On 4/1/2019 3:04 PM, Sam wrote:
 
>> Jesus!
 
> No, I'm not him. But that was an understandable mistake.
 
Agreed. :)
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: