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


Groups > comp.lang.c++ > #67072 > unrolled thread

Why does this work on Xcode ???

Started byBob Langelaan <bobl0456@gmail.com>
First post2019-07-16 22:03 -0700
Last post2019-08-10 09:29 -0700
Articles 20 on this page of 47 — 14 participants

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


Contents

  Why does this work on Xcode ??? Bob Langelaan <bobl0456@gmail.com> - 2019-07-16 22:03 -0700
    Re: Why does this work on Xcode ??? Paavo Helde <myfirstname@osa.pri.ee> - 2019-07-17 08:46 +0300
    Re: Why does this work on Xcode ??? Öö Tiib <ootiib@hot.ee> - 2019-07-17 00:06 -0700
      Re: Why does this work on Xcode ??? Öö Tiib <ootiib@hot.ee> - 2019-07-17 01:44 -0700
    Re: Why does this work on Xcode ??? Juha Nieminen <nospam@thanks.invalid> - 2019-07-17 07:46 +0000
    Re: Why does this work on Xcode ??? James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-07-17 09:12 -0400
    Re: Why does this work on Xcode ??? "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2019-07-17 17:01 +0200
      Re: Why does this work on Xcode ??? Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk> - 2019-07-17 22:15 +0100
        Re: Why does this work on Xcode ??? "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2019-07-17 23:29 +0200
          Re: Why does this work on Xcode ??? Christian Gollwitzer <auriocus@gmx.de> - 2019-07-19 08:27 +0200
            Re: Why does this work on Xcode ??? "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2019-07-19 09:09 +0200
              Re: Why does this work on Xcode ??? "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2019-07-19 09:24 +0200
              Re: Why does this work on Xcode ??? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-08-10 11:18 -0700
                Re: Why does this work on Xcode ??? "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2019-08-10 21:05 +0200
                  Re: Why does this work on Xcode ??? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-08-22 10:28 -0700
                    Re: Why does this work on Xcode ??? "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2019-08-22 19:50 +0200
                      Re: Why does this work on Xcode ??? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-08-22 23:45 +0100
                        Re: Why does this work on Xcode ??? "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2019-08-23 07:22 +0200
                          Re: Why does this work on Xcode ??? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-08-23 13:12 +0100
                            Re: Why does this work on Xcode ??? "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2019-08-23 16:02 +0200
                            Re: Why does this work on Xcode ??? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-09-18 08:50 -0700
                          Re: Why does this work on Xcode ??? James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-08-23 09:28 -0400
                            Re: Why does this work on Xcode ??? David Brown <david.brown@hesbynett.no> - 2019-08-23 16:37 +0200
                              Re: Why does this work on Xcode ??? "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2019-08-23 23:07 +0200
                                Re: Why does this work on Xcode ??? Richard Damon <Richard@Damon-Family.org> - 2019-08-23 19:10 -0400
                                  Re: Why does this work on Xcode ??? "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2019-08-24 06:49 +0200
                                Re: Why does this work on Xcode ??? James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-08-23 19:49 -0400
                                  Re: Why does this work on Xcode ??? "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2019-08-24 06:45 +0200
                                    Re: Why does this work on Xcode ??? David Brown <david.brown@hesbynett.no> - 2019-08-25 12:06 +0200
                                      Re: Why does this work on Xcode ??? "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2019-08-25 13:25 +0200
                                        Re: Why does this work on Xcode ??? David Brown <david.brown@hesbynett.no> - 2019-08-25 15:11 +0200
                                          Re: Why does this work on Xcode ??? "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2019-08-25 17:12 +0200
                                            Re: Why does this work on Xcode ??? David Brown <david.brown@hesbynett.no> - 2019-08-25 23:32 +0200
                                              Re: Why does this work on Xcode ??? "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2019-08-26 11:51 +0200
                                                Re: Why does this work on Xcode ??? David Brown <david.brown@hesbynett.no> - 2019-08-26 13:26 +0200
                                Re: Why does this work on Xcode ??? David Brown <david.brown@hesbynett.no> - 2019-08-25 11:36 +0200
                                  Re: Why does this work on Xcode ??? "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2019-08-25 13:27 +0200
                                    Re: Why does this work on Xcode ??? David Brown <david.brown@hesbynett.no> - 2019-08-25 15:15 +0200
                                    Re: Why does this work on Xcode ??? James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-08-26 00:43 -0400
                          Re: Why does this work on Xcode ??? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-08-24 04:58 -0700
                      Re: Why does this work on Xcode ??? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-08-26 09:53 -0700
                      Re: Why does this work on Xcode ??? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-08-28 18:03 -0700
            Re: Why does this work on Xcode ??? Öö Tiib <ootiib@hot.ee> - 2019-07-19 00:20 -0700
            Re: Why does this work on Xcode ??? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-08-09 07:41 -0700
        Re: Why does this work on Xcode ??? Bonita Montero <Bonita.Montero@gmail.com> - 2019-08-24 19:49 +0200
      Re: Why does this work on Xcode ??? Jorgen Grahn <grahn+nntp@snipabacken.se> - 2019-07-21 11:41 +0000
        Re: Why does this work on Xcode ??? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-08-10 09:29 -0700

Page 2 of 3 — ← Prev page 1 [2] 3  Next page →


#68507

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2019-09-18 08:50 -0700
Message-ID<8636gt4n8w.fsf@linuxsc.com>
In reply to#67903
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:

> Tim is a far better writer than I am [...]

I'm not sure I deserve this compliment but I do very much
appreciate it.

[toc] | [prev] | [next] | [standalone]


#67907

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2019-08-23 09:28 -0400
Message-ID<qjoplk$ep$1@dont-email.me>
In reply to#67898
On 8/23/19 1:22 AM, Alf P. Steinbach wrote:
> On 23.08.2019 00:45, Ben Bacarisse wrote:
>> "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> writes:
>> <cut>
>>> And I don't think you think you're smarter than everybody else in this
>>> group just for holding an opinion on UB that nobody else here shares.
>>
>> Why do you think no one else shares Tim's opinion?
> 
> Because he's been arguing his view for a very long time and nobody's 
> supported him.

I normally try (and often fail) to avoid paying attention to his posts,
because I've found discussions with him to be unproductive - when I
discuss my disagreements with him, we usually both end up wasting a lot
of time failing to convince each other. He's a lot like you in that regard.

He has a strong tendency to elevate what he believes to be the
committee's intent to play a larger role in the interpretation of the
standard than I think appropriate. This can be particularly annoying if
I disagree with him about what that intent was.
If the standard's wording is in conflict with (or even simply fails to
clearly express) the committee's intent, then that wording should be
corrected to clearly express that intent - but that discrepancy doesn't
change the meaning of the words that they actually wrote.

However, he is very knowledgeable about the standard, and he is correct
about the pre-eminence of a program's observable behavior. The
standard's definition of "observable behavior" is not "behavior which
can be observed" - it's far more specific than that:

"The least requirements on a conforming implementation are:
— Accesses through volatile glvalues are evaluated strictly according to
the rules of the abstract machine.
— At program termination, all data written into files shall be identical
to one of the possible results that
execution of the program according to the abstract semantics would have
produced.
— The input and output dynamics of interactive devices shall take place
in such a fashion that prompting
output is actually delivered before a program waits for input. What
constitutes an interactive device is
implementation-defined.
These collectively are referred to as the observable behavior of the
program. ..." (4.6p7).

The term "observable behavior" is in italics, an ISO convention
indicating that this sentence is the official definition of that term.
In the context of the C++ standard, that definition overrides any
alternative interpretation that might otherwise seem appropriate.

Note that the amount of stack space taken up by a program does not
qualify as "observable behavior".

The standard very explicitly says "The semantic descriptions in this
International Standard define a parameterized nondeterministic abstract
machine. This International Standard places no requirement on the
structure of conforming implementations. In particular, they need not
copy or emulate the structure of the abstract machine. Rather,
conforming implementations are required to emulate (only) the observable
behavior of the abstract machine as explained below." (4.6p1).

So if the same observable behavior can be achieved by using either an
iterative or a recursive algorithm, an implementation is free to use
either of those algorithms to achieve it, regardless of which algorithm
you actually expressed in your code. The fact that one algorithm runs a
higher risk of running out of stack space than the other imposes no
requirement on the implementation to avoid that risk (or to embrace it,
for that matter).

[toc] | [prev] | [next] | [standalone]


#67909

FromDavid Brown <david.brown@hesbynett.no>
Date2019-08-23 16:37 +0200
Message-ID<qjotnh$p13$1@dont-email.me>
In reply to#67907
On 23/08/2019 15:28, James Kuyper wrote:
> On 8/23/19 1:22 AM, Alf P. Steinbach wrote:
>> On 23.08.2019 00:45, Ben Bacarisse wrote:
>>> "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> writes:
>>> <cut>
>>>> And I don't think you think you're smarter than everybody else in this
>>>> group just for holding an opinion on UB that nobody else here shares.
>>>
>>> Why do you think no one else shares Tim's opinion?
>>
>> Because he's been arguing his view for a very long time and nobody's 
>> supported him.
> 
> I normally try (and often fail) to avoid paying attention to his posts,
> because I've found discussions with him to be unproductive - when I
> discuss my disagreements with him, we usually both end up wasting a lot
> of time failing to convince each other. He's a lot like you in that regard.
> 
> He has a strong tendency to elevate what he believes to be the
> committee's intent to play a larger role in the interpretation of the
> standard than I think appropriate. This can be particularly annoying if
> I disagree with him about what that intent was.
> If the standard's wording is in conflict with (or even simply fails to
> clearly express) the committee's intent, then that wording should be
> corrected to clearly express that intent - but that discrepancy doesn't
> change the meaning of the words that they actually wrote.
> 
> However, he is very knowledgeable about the standard, and he is correct
> about the pre-eminence of a program's observable behavior. The
> standard's definition of "observable behavior" is not "behavior which
> can be observed" - it's far more specific than that:
> 
> "The least requirements on a conforming implementation are:
> — Accesses through volatile glvalues are evaluated strictly according to
> the rules of the abstract machine.
> — At program termination, all data written into files shall be identical
> to one of the possible results that
> execution of the program according to the abstract semantics would have
> produced.
> — The input and output dynamics of interactive devices shall take place
> in such a fashion that prompting
> output is actually delivered before a program waits for input. What
> constitutes an interactive device is
> implementation-defined.
> These collectively are referred to as the observable behavior of the
> program. ..." (4.6p7).
> 
> The term "observable behavior" is in italics, an ISO convention
> indicating that this sentence is the official definition of that term.
> In the context of the C++ standard, that definition overrides any
> alternative interpretation that might otherwise seem appropriate.
> 
> Note that the amount of stack space taken up by a program does not
> qualify as "observable behavior".
> 
> The standard very explicitly says "The semantic descriptions in this
> International Standard define a parameterized nondeterministic abstract
> machine. This International Standard places no requirement on the
> structure of conforming implementations. In particular, they need not
> copy or emulate the structure of the abstract machine. Rather,
> conforming implementations are required to emulate (only) the observable
> behavior of the abstract machine as explained below." (4.6p1).
> 
> So if the same observable behavior can be achieved by using either an
> iterative or a recursive algorithm, an implementation is free to use
> either of those algorithms to achieve it, regardless of which algorithm
> you actually expressed in your code. The fact that one algorithm runs a
> higher risk of running out of stack space than the other imposes no
> requirement on the implementation to avoid that risk (or to embrace it,
> for that matter).
> 

Since we are expressing opinions - regardless of how much or little they
may be worth - I agree with James here.  And as far as I can see, it is
the same as Tim has been saying in this regard.

Usually, changing an iterative algorithm into a recursive one will be a
pessimisation, taking more space and run-time.  So it is highly unlikely
for a compiler to do this sort of thing - it would quickly become an
unpopular tool.  But it is allowed to do so.

In the same way, between "int a = b + c;" and "int d = a * 2;", the
compiler is allowed to insert code calculating the first hundred digits
of pi - including the stack space needed for the job.  It would be an
unpopular tool, but this would not affect the observable behaviour and
thus it would not affect the conformance of the compiler.

The standards do not impose any requirements on quality of
implementation (though they have a few hints here and there) - that is
up to the user.

[toc] | [prev] | [next] | [standalone]


#67917

From"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>
Date2019-08-23 23:07 +0200
Message-ID<qjpki9$vhs$1@dont-email.me>
In reply to#67909
On 23.08.2019 16:37, David Brown wrote:
> On 23/08/2019 15:28, James Kuyper wrote:
>> On 8/23/19 1:22 AM, Alf P. Steinbach wrote:
>>> On 23.08.2019 00:45, Ben Bacarisse wrote:
>>>> "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> writes:
>>>> <cut>
>>>>> And I don't think you think you're smarter than everybody else in this
>>>>> group just for holding an opinion on UB that nobody else here shares.
>>>>
>>>> Why do you think no one else shares Tim's opinion?
>>>
>>> Because he's been arguing his view for a very long time and nobody's
>>> supported him.
>>
>> I normally try (and often fail) to avoid paying attention to his posts,
>> because I've found discussions with him to be unproductive - when I
>> discuss my disagreements with him, we usually both end up wasting a lot
>> of time failing to convince each other. He's a lot like you in that regard.
>>
>> He has a strong tendency to elevate what he believes to be the
>> committee's intent to play a larger role in the interpretation of the
>> standard than I think appropriate. This can be particularly annoying if
>> I disagree with him about what that intent was.
>> If the standard's wording is in conflict with (or even simply fails to
>> clearly express) the committee's intent, then that wording should be
>> corrected to clearly express that intent - but that discrepancy doesn't
>> change the meaning of the words that they actually wrote.
>>
>> However, he is very knowledgeable about the standard, and he is correct
>> about the pre-eminence of a program's observable behavior. The
>> standard's definition of "observable behavior" is not "behavior which
>> can be observed" - it's far more specific than that:
>>
>> "The least requirements on a conforming implementation are:
>> — Accesses through volatile glvalues are evaluated strictly according to
>> the rules of the abstract machine.
>> — At program termination, all data written into files shall be identical
>> to one of the possible results that
>> execution of the program according to the abstract semantics would have
>> produced.
>> — The input and output dynamics of interactive devices shall take place
>> in such a fashion that prompting
>> output is actually delivered before a program waits for input. What
>> constitutes an interactive device is
>> implementation-defined.
>> These collectively are referred to as the observable behavior of the
>> program. ..." (4.6p7).
>>
>> The term "observable behavior" is in italics, an ISO convention
>> indicating that this sentence is the official definition of that term.
>> In the context of the C++ standard, that definition overrides any
>> alternative interpretation that might otherwise seem appropriate.
>>
>> Note that the amount of stack space taken up by a program does not
>> qualify as "observable behavior".
>>
>> The standard very explicitly says "The semantic descriptions in this
>> International Standard define a parameterized nondeterministic abstract
>> machine. This International Standard places no requirement on the
>> structure of conforming implementations. In particular, they need not
>> copy or emulate the structure of the abstract machine. Rather,
>> conforming implementations are required to emulate (only) the observable
>> behavior of the abstract machine as explained below." (4.6p1).
>>
>> So if the same observable behavior can be achieved by using either an
>> iterative or a recursive algorithm, an implementation is free to use
>> either of those algorithms to achieve it, regardless of which algorithm
>> you actually expressed in your code. The fact that one algorithm runs a
>> higher risk of running out of stack space than the other imposes no
>> requirement on the implementation to avoid that risk (or to embrace it,
>> for that matter).
>>
> 
> Since we are expressing opinions - regardless of how much or little they
> may be worth - I agree with James here.  And as far as I can see, it is
> the same as Tim has been saying in this regard.
> 
> Usually, changing an iterative algorithm into a recursive one will be a
> pessimisation, taking more space and run-time.  So it is highly unlikely
> for a compiler to do this sort of thing - it would quickly become an
> unpopular tool.  But it is allowed to do so.

As an example, rewriting a function with loop that uses a fixed size 
storage known at compile time, to a recursive function that uses storage 
proportional to the function argument, changes the behavior.

With the original code one is guaranteed that it will complete.

With the recursive one one is not guaranteed completion, because for 
large enough values of the parameter it will run out of stack space, an 
implementation limit.

   * * *

Essentially the argument about observable behavior is therefore that a 
compiler is formally permitted to change a program that guarantees a 
result if it compiles and loads, into a program that almost guaranteed 
does not produce a correct result.

That's a perpetuum mobile construction argument. One doesn't necessarily 
know where someone's logic went astray so that they ended up with a 
perpetuum mobile design, but the end result is just not reality: it's 
absurd. Somewhere in that argument there's necessarily something wrong, 
and that's not a QoI issue.


> In the same way, between "int a = b + c;" and "int d = a * 2;", the
> compiler is allowed to insert code calculating the first hundred digits
> of pi - including the stack space needed for the job.

No, that's not the same way.

In this example a fixed storage requirement is not changed to a 
requirement of storage depending on a parameter.


>  It would be an
> unpopular tool, but this would not affect the observable behaviour and
> thus it would not affect the conformance of the compiler.

It would affect observable behavior. One would get wrong results or 
crashes. Instead of with a conforming compiler, correct results.


> The standards do not impose any requirements on quality of
> implementation (though they have a few hints here and there) - that is
> up to the user.

That's right, but this isn't QoI, it's about correctness.


Cheers!,

- Alf

[toc] | [prev] | [next] | [standalone]


#67918

FromRichard Damon <Richard@Damon-Family.org>
Date2019-08-23 19:10 -0400
Message-ID<Cn_7F.31037$O63.25583@fx26.iad>
In reply to#67917
On 8/23/19 5:07 PM, Alf P. Steinbach wrote:
> On 23.08.2019 16:37, David Brown wrote:
>> On 23/08/2019 15:28, James Kuyper wrote:
>>> On 8/23/19 1:22 AM, Alf P. Steinbach wrote:
>>>> On 23.08.2019 00:45, Ben Bacarisse wrote:
>>>>> "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> writes:
>>>>> <cut>
>>>>>> And I don't think you think you're smarter than everybody else in
>>>>>> this
>>>>>> group just for holding an opinion on UB that nobody else here shares.
>>>>>
>>>>> Why do you think no one else shares Tim's opinion?
>>>>
>>>> Because he's been arguing his view for a very long time and nobody's
>>>> supported him.
>>>
>>> I normally try (and often fail) to avoid paying attention to his posts,
>>> because I've found discussions with him to be unproductive - when I
>>> discuss my disagreements with him, we usually both end up wasting a lot
>>> of time failing to convince each other. He's a lot like you in that
>>> regard.
>>>
>>> He has a strong tendency to elevate what he believes to be the
>>> committee's intent to play a larger role in the interpretation of the
>>> standard than I think appropriate. This can be particularly annoying if
>>> I disagree with him about what that intent was.
>>> If the standard's wording is in conflict with (or even simply fails to
>>> clearly express) the committee's intent, then that wording should be
>>> corrected to clearly express that intent - but that discrepancy doesn't
>>> change the meaning of the words that they actually wrote.
>>>
>>> However, he is very knowledgeable about the standard, and he is correct
>>> about the pre-eminence of a program's observable behavior. The
>>> standard's definition of "observable behavior" is not "behavior which
>>> can be observed" - it's far more specific than that:
>>>
>>> "The least requirements on a conforming implementation are:
>>> — Accesses through volatile glvalues are evaluated strictly according to
>>> the rules of the abstract machine.
>>> — At program termination, all data written into files shall be identical
>>> to one of the possible results that
>>> execution of the program according to the abstract semantics would have
>>> produced.
>>> — The input and output dynamics of interactive devices shall take place
>>> in such a fashion that prompting
>>> output is actually delivered before a program waits for input. What
>>> constitutes an interactive device is
>>> implementation-defined.
>>> These collectively are referred to as the observable behavior of the
>>> program. ..." (4.6p7).
>>>
>>> The term "observable behavior" is in italics, an ISO convention
>>> indicating that this sentence is the official definition of that term.
>>> In the context of the C++ standard, that definition overrides any
>>> alternative interpretation that might otherwise seem appropriate.
>>>
>>> Note that the amount of stack space taken up by a program does not
>>> qualify as "observable behavior".
>>>
>>> The standard very explicitly says "The semantic descriptions in this
>>> International Standard define a parameterized nondeterministic abstract
>>> machine. This International Standard places no requirement on the
>>> structure of conforming implementations. In particular, they need not
>>> copy or emulate the structure of the abstract machine. Rather,
>>> conforming implementations are required to emulate (only) the observable
>>> behavior of the abstract machine as explained below." (4.6p1).
>>>
>>> So if the same observable behavior can be achieved by using either an
>>> iterative or a recursive algorithm, an implementation is free to use
>>> either of those algorithms to achieve it, regardless of which algorithm
>>> you actually expressed in your code. The fact that one algorithm runs a
>>> higher risk of running out of stack space than the other imposes no
>>> requirement on the implementation to avoid that risk (or to embrace it,
>>> for that matter).
>>>
>>
>> Since we are expressing opinions - regardless of how much or little they
>> may be worth - I agree with James here.  And as far as I can see, it is
>> the same as Tim has been saying in this regard.
>>
>> Usually, changing an iterative algorithm into a recursive one will be a
>> pessimisation, taking more space and run-time.  So it is highly unlikely
>> for a compiler to do this sort of thing - it would quickly become an
>> unpopular tool.  But it is allowed to do so.
> 
> As an example, rewriting a function with loop that uses a fixed size
> storage known at compile time, to a recursive function that uses storage
> proportional to the function argument, changes the behavior.
> 
> With the original code one is guaranteed that it will complete.
> 
> With the recursive one one is not guaranteed completion, because for
> large enough values of the parameter it will run out of stack space, an
> implementation limit.
> 
>   * * *
> 
> Essentially the argument about observable behavior is therefore that a
> compiler is formally permitted to change a program that guarantees a
> result if it compiles and loads, into a program that almost guaranteed
> does not produce a correct result.
> 
> That's a perpetuum mobile construction argument. One doesn't necessarily
> know where someone's logic went astray so that they ended up with a
> perpetuum mobile design, but the end result is just not reality: it's
> absurd. Somewhere in that argument there's necessarily something wrong,
> and that's not a QoI issue.
> 
> 
>> In the same way, between "int a = b + c;" and "int d = a * 2;", the
>> compiler is allowed to insert code calculating the first hundred digits
>> of pi - including the stack space needed for the job.
> 
> No, that's not the same way.
> 
> In this example a fixed storage requirement is not changed to a
> requirement of storage depending on a parameter.
> 
> 
>>  It would be an
>> unpopular tool, but this would not affect the observable behaviour and
>> thus it would not affect the conformance of the compiler.
> 
> It would affect observable behavior. One would get wrong results or
> crashes. Instead of with a conforming compiler, correct results.
> 
> 
>> The standards do not impose any requirements on quality of
>> implementation (though they have a few hints here and there) - that is
>> up to the user.
> 
> That's right, but this isn't QoI, it's about correctness.
> 
> 
> Cheers!,
> 
> - Alf

The Standards unfortunately leave a LOT to QoI.

For instance, as far as I know, the compiler would be free to implement

unsigned i = 1;
unsigned j = 5;
unsigned k = i + j;

as
  k = __add_uint(i, j);

where __add_uint() was defined as:

unsigned __add_uint(unsigned i, unsigned j) {
  if(j) return __add_uint(++i, --j);
  else return i;
}

You might even need something like this (but maybe iterative instead of
recursive) for a processor with very limited arithmetic operations (just
increment/decrement).

One such an implementation, the program

int main() {
  unsigned i = 1U + 65000U;
}

might fail due to exhaustion of resources, and that is ok by the
standard. The Standard just requires that there be ONE program that
reaches all of the specified resource limits that the implementation can
process, any other program is allowed to fail for resource limits. This
'one program' rule is one of the big holes in the Standard (at least in
my opinion).

[toc] | [prev] | [next] | [standalone]


#67921

From"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>
Date2019-08-24 06:49 +0200
Message-ID<qjqfk2$ou8$1@dont-email.me>
In reply to#67918
On 24.08.2019 01:10, Richard Damon wrote:
> 
> The Standards unfortunately leave a LOT to QoI.
> 
> For instance, as far as I know, the compiler would be free to implement
> 
> unsigned i = 1;
> unsigned j = 5;
> unsigned k = i + j;
> 
> as
>    k = __add_uint(i, j);
> 
> where __add_uint() was defined as:
> 
> unsigned __add_uint(unsigned i, unsigned j) {
>    if(j) return __add_uint(++i, --j);
>    else return i;
> }
> 

This is an argument by repeated assertion.

True, that's been the nature of the discussion so far. But in order to 
break that cycle (if that's possible), I cut this sub-thread here, as 
far as I'm concerned. Hopefully others won't chime in. :)


Cheers!,

- Alf

[toc] | [prev] | [next] | [standalone]


#67919

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2019-08-23 19:49 -0400
Message-ID<qjpu1j$hcq$1@dont-email.me>
In reply to#67917
On 8/23/19 5:07 PM, Alf P. Steinbach wrote:
> On 23.08.2019 16:37, David Brown wrote:
>> On 23/08/2019 15:28, James Kuyper wrote:
...
>>> "The least requirements on a conforming implementation are:
>>> — Accesses through volatile glvalues are evaluated strictly according to
>>> the rules of the abstract machine.
>>> — At program termination, all data written into files shall be identical
>>> to one of the possible results that
>>> execution of the program according to the abstract semantics would have
>>> produced.
>>> — The input and output dynamics of interactive devices shall take place
>>> in such a fashion that prompting
>>> output is actually delivered before a program waits for input. What
>>> constitutes an interactive device is
>>> implementation-defined.
>>> These collectively are referred to as the observable behavior of the
>>> program. ..." (4.6p7).
>>>
>>> The term "observable behavior" is in italics, an ISO convention
>>> indicating that this sentence is the official definition of that term.
>>> In the context of the C++ standard, that definition overrides any
>>> alternative interpretation that might otherwise seem appropriate.
>>>
>>> Note that the amount of stack space taken up by a program does not
>>> qualify as "observable behavior".
>>>
>>> The standard very explicitly says "The semantic descriptions in this
>>> International Standard define a parameterized nondeterministic abstract
>>> machine. This International Standard places no requirement on the
>>> structure of conforming implementations. In particular, they need not
>>> copy or emulate the structure of the abstract machine. Rather,
>>> conforming implementations are required to emulate (only) the observable
>>> behavior of the abstract machine as explained below." (4.6p1).
>>>
>>> So if the same observable behavior can be achieved by using either an
>>> iterative or a recursive algorithm, an implementation is free to use
>>> either of those algorithms to achieve it, regardless of which algorithm
>>> you actually expressed in your code. The fact that one algorithm runs a
>>> higher risk of running out of stack space than the other imposes no
>>> requirement on the implementation to avoid that risk (or to embrace it,
>>> for that matter).
>>>
>>
>> Since we are expressing opinions - regardless of how much or little they
>> may be worth - I agree with James here.  And as far as I can see, it is
>> the same as Tim has been saying in this regard.
>>
>> Usually, changing an iterative algorithm into a recursive one will be a
>> pessimisation, taking more space and run-time.  So it is highly unlikely
>> for a compiler to do this sort of thing - it would quickly become an
>> unpopular tool.  But it is allowed to do so.
> 
> As an example, rewriting a function with loop that uses a fixed size 
> storage known at compile time, to a recursive function that uses storage 
> proportional to the function argument, changes the behavior.

It doesn't change the observable behavior. Stack usage isn't observable.
The observable behavior won't occur at all if the program runs out of
stack space, but that's also a possibility for the iterative version of
the program, so it doesn't count as a difference in the observable behavior.

> With the original code one is guaranteed that it will complete.

From what do you derive that guarantee? What minimum amount of stack
does the standard require an implementation to provide? What upper limit
does the standard impose on the amount of stack used up by the iterative
version of that program?

In case you're having trouble locating the relevant clauses, let me give
you a hint: they don't exist. The standard doesn't say anything about
either issue. It says precisely as much about those issues for the
recursive version of the program as it does about the iterative version
- which is nothing at all.

What the standard does say that's relevant is "If a program contains no
violations of the rules in this International Standard, a conforming
implementation shall, within its resource limits, accept and correctly
execute 2 that program." (4.1p2). Note the key exception - "within its
resource limits". That's the phrase that gives the recursive version of
the program permission to fail if it runs out of stack; stack space is
one of the implementation's resources, and it is in fact limited. That
same phrase also gives the iterative version of the program permission
to fail, for precisely the same reason. The iterative version is less
likely to run out of stack space, but it's not guaranteed to have enough
stack space, any more than the recursive version is.

> Essentially the argument about observable behavior is therefore that a 
> compiler is formally permitted to change a program that guarantees a 
> result if it compiles and loads, into a program that almost guaranteed 
> does not produce a correct result.

No, if the iterative version of the program was guaranteed to succeed,
this would not be a permitted rearrangement of the code. The only
relevant guarantee has an escape clause that can be used to justify
either version of the code failing.

> absurd. Somewhere in that argument there's necessarily something wrong, 
> and that's not a QoI issue.

Having enough stack available to allow either version of the program to
complete is entirely a matter of QoI - the standard says nothing about
the issue, except to provide "resource limits" as a permissible reason
for a program to fail.

[toc] | [prev] | [next] | [standalone]


#67920

From"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>
Date2019-08-24 06:45 +0200
Message-ID<qjqfe5$o97$1@dont-email.me>
In reply to#67919
On 24.08.2019 01:49, James Kuyper wrote:
> On 8/23/19 5:07 PM, Alf P. Steinbach wrote:
>> On 23.08.2019 16:37, David Brown wrote:
>>> On 23/08/2019 15:28, James Kuyper wrote:
> ...
>>>> "The least requirements on a conforming implementation are:
>>>> — Accesses through volatile glvalues are evaluated strictly according to
>>>> the rules of the abstract machine.
>>>> — At program termination, all data written into files shall be identical
>>>> to one of the possible results that
>>>> execution of the program according to the abstract semantics would have
>>>> produced.
>>>> — The input and output dynamics of interactive devices shall take place
>>>> in such a fashion that prompting
>>>> output is actually delivered before a program waits for input. What
>>>> constitutes an interactive device is
>>>> implementation-defined.
>>>> These collectively are referred to as the observable behavior of the
>>>> program. ..." (4.6p7).
>>>>
>>>> The term "observable behavior" is in italics, an ISO convention
>>>> indicating that this sentence is the official definition of that term.
>>>> In the context of the C++ standard, that definition overrides any
>>>> alternative interpretation that might otherwise seem appropriate.
>>>>
>>>> Note that the amount of stack space taken up by a program does not
>>>> qualify as "observable behavior".
>>>>
>>>> The standard very explicitly says "The semantic descriptions in this
>>>> International Standard define a parameterized nondeterministic abstract
>>>> machine. This International Standard places no requirement on the
>>>> structure of conforming implementations. In particular, they need not
>>>> copy or emulate the structure of the abstract machine. Rather,
>>>> conforming implementations are required to emulate (only) the observable
>>>> behavior of the abstract machine as explained below." (4.6p1).
>>>>
>>>> So if the same observable behavior can be achieved by using either an
>>>> iterative or a recursive algorithm, an implementation is free to use
>>>> either of those algorithms to achieve it, regardless of which algorithm
>>>> you actually expressed in your code. The fact that one algorithm runs a
>>>> higher risk of running out of stack space than the other imposes no
>>>> requirement on the implementation to avoid that risk (or to embrace it,
>>>> for that matter).
>>>>
>>>
>>> Since we are expressing opinions - regardless of how much or little they
>>> may be worth - I agree with James here.  And as far as I can see, it is
>>> the same as Tim has been saying in this regard.
>>>
>>> Usually, changing an iterative algorithm into a recursive one will be a
>>> pessimisation, taking more space and run-time.  So it is highly unlikely
>>> for a compiler to do this sort of thing - it would quickly become an
>>> unpopular tool.  But it is allowed to do so.
>>
>> As an example, rewriting a function with loop that uses a fixed size
>> storage known at compile time, to a recursive function that uses storage
>> proportional to the function argument, changes the behavior.
> 
> It doesn't change the observable behavior. Stack usage isn't observable.
> The observable behavior won't occur at all if the program runs out of
> stack space, but that's also a possibility for the iterative version of
> the program, so it doesn't count as a difference in the observable behavior.
> 
>> With the original code one is guaranteed that it will complete.
> 
>  From what do you derive that guarantee?

The standard guarantees it. "shall ... within its resource limits ... 
correctly execute that program".

When the resource requirements are known at compile time, there is no 
question about it: if the program loads, and the provided resources are 
sufficient for those known requirements, it will execute correctly.


> What minimum amount of stack
> does the standard require an implementation to provide?

The standard doesn't, AFAIK, say anything about minimum storage, but 
that doesn't matter. When the program's resource requirements are known 
at compile time one can provide sufficient resources for those known 
requirements.

In practice, as you know, that's done by specifying the minimum stack 
size in the build of the program, which ensures that it either loads and 
runs correctly, or else fails to load. But conceivably it could be done 
in other ways, even for each execution. However it's done, when a fixed 
resource requirements program produced by a conforming compiler is run, 
it produces a correct result.

One /can/ rely on a C++ program to produce correct results.

When one ensures that it will not exceed the implementation's resource 
limits.

It's a different matter when the resource requirements are not known 
until run time, as with a transformation from iterative to recursive. 
Then one cannot in general provide guaranteed sufficient resources. 
Instead one may end up with a program that always or nearly always 
produce incorrect results, even, since this is the nature of UB, without 
any indication that the results are wrong.

Note that such transformations include an implementation whose 
executables, possibly except for `int main(){}`, /never/ work.

So then one /cannot/ rely on a C++ program to produce correct results.

Again, that a compiler can produce only non-functioning programs and 
still be formally correct is absurd, only an interpretation for children 
or academics. Such a compiler fails all requirements on a C++ compiler: 
it's not a QoI issue. You're arguing that instead, like the watch that 
just displays "NOW", it can be the most conforming compiler ever, whose 
executables never do anything formally wrong, and that's meaningless.


> What upper limit
> does the standard impose on the amount of stack used up by the iterative
> version of that program?

That's an irrelevant nonsense question.

When the resource requirements are known at compile time, there is no 
question about it: if the program loads, and the provided resources are 
sufficient for those known requirements, it will execute correctly.


[snip]

Cheers & hth.,

- Alf

[toc] | [prev] | [next] | [standalone]


#67932

FromDavid Brown <david.brown@hesbynett.no>
Date2019-08-25 12:06 +0200
Message-ID<qjtmjl$pfp$1@dont-email.me>
In reply to#67920
On 24/08/2019 06:45, Alf P. Steinbach wrote:
> On 24.08.2019 01:49, James Kuyper wrote:
>> On 8/23/19 5:07 PM, Alf P. Steinbach wrote:
>>> On 23.08.2019 16:37, David Brown wrote:
>>>> On 23/08/2019 15:28, James Kuyper wrote:
>> ...

>> It doesn't change the observable behavior. Stack usage isn't observable.
>> The observable behavior won't occur at all if the program runs out of
>> stack space, but that's also a possibility for the iterative version of
>> the program, so it doesn't count as a difference in the observable
>> behavior.
>>
>>> With the original code one is guaranteed that it will complete.
>>
>>  From what do you derive that guarantee?
> 
> The standard guarantees it. "shall ... within its resource limits ...
> correctly execute that program".
> 
> When the resource requirements are known at compile time, there is no
> question about it: if the program loads, and the provided resources are
> sufficient for those known requirements, it will execute correctly.
> 

The resource requirements most certainly are /not/ known at compile time
in general.  There are exceptions, but they are very much exceptions -
for some kinds of embedded system development you can do enough static
analysis to be sure of stack usage (and typically you don't have heap
usage at all).

Are you suggesting that during the typical Windows program compilation,
the compiler knows the stack requirements of all functions called in
DLLs?  Are you suggesting that during compilation, the compiler knows
the size of the RAM on the system it will run on?  Are you suggesting
the compiler knows the size of the data files provided by the user?


> 
>> What minimum amount of stack
>> does the standard require an implementation to provide?
> 
> The standard doesn't, AFAIK, say anything about minimum storage, but
> that doesn't matter. When the program's resource requirements are known
> at compile time one can provide sufficient resources for those known
> requirements.

That's nice in theory, though completely unsupported by the standard and
completely missing in almost every practical case.  I'm taking figures
out the air here, but I'd guess that for a minimum 99.9% of C and C++
programs, stack space either grows automatically as needed or the fixed
size is picked as "this is going to be /way/ more than we need".

> 
> In practice, as you know, that's done by specifying the minimum stack
> size in the build of the program, which ensures that it either loads and
> runs correctly, or else fails to load. 

That might be true in very limited practice.  But you can't extrapolate
from experience of one Windows compiler and a misunderstanding of the
difference between a compiler and a linker, and assume it applies "in
practice" for other cases.

> But conceivably it could be done
> in other ways, even for each execution. However it's done, when a fixed
> resource requirements program produced by a conforming compiler is run,
> it produces a correct result.
> 
> One /can/ rely on a C++ program to produce correct results.
> 
> When one ensures that it will not exceed the implementation's resource
> limits.

Of course.  The standards say as much.

> 
> It's a different matter when the resource requirements are not known
> until run time, as with a transformation from iterative to recursive.

They are almost never known.  Making a transformation from an iterative
to a recursive algorithm is likely to make stack requirements "more
unknown".  And no one disagrees that that is a bad thing.  But where you
are /wrong/ is thinking that avoiding such transformations makes stack
requirements known, or that it is remotely relevant to conformance or
observable behaviour as defined by the standards.

> Then one cannot in general provide guaranteed sufficient resources.
> Instead one may end up with a program that always or nearly always
> produce incorrect results, even, since this is the nature of UB, without
> any indication that the results are wrong.
> 
> Note that such transformations include an implementation whose
> executables, possibly except for `int main(){}`, /never/ work.
> 
> So then one /cannot/ rely on a C++ program to produce correct results.
> 
> Again, that a compiler can produce only non-functioning programs and
> still be formally correct is absurd, only an interpretation for children
> or academics. Such a compiler fails all requirements on a C++ compiler:
> it's not a QoI issue. You're arguing that instead, like the watch that
> just displays "NOW", it can be the most conforming compiler ever, whose
> executables never do anything formally wrong, and that's meaningless.
> 
> 
>> What upper limit
>> does the standard impose on the amount of stack used up by the iterative
>> version of that program?
> 
> That's an irrelevant nonsense question.
> 
> When the resource requirements are known at compile time, there is no
> question about it: if the program loads, and the provided resources are
> sufficient for those known requirements, it will execute correctly.
> 
> 
> [snip]
> 
> Cheers & hth.,
> 
> - Alf

[toc] | [prev] | [next] | [standalone]


#67935

From"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>
Date2019-08-25 13:25 +0200
Message-ID<qjtr6v$hvu$1@dont-email.me>
In reply to#67932
On 25.08.2019 12:06, David Brown wrote:
> On 24/08/2019 06:45, Alf P. Steinbach wrote:
>> On 24.08.2019 01:49, James Kuyper wrote:
>>> On 8/23/19 5:07 PM, Alf P. Steinbach wrote:
>>>> On 23.08.2019 16:37, David Brown wrote:
>>>>> On 23/08/2019 15:28, James Kuyper wrote:
>>> ...
> 
>>> It doesn't change the observable behavior. Stack usage isn't observable.
>>> The observable behavior won't occur at all if the program runs out of
>>> stack space, but that's also a possibility for the iterative version of
>>> the program, so it doesn't count as a difference in the observable
>>> behavior.
>>>
>>>> With the original code one is guaranteed that it will complete.
>>>
>>>   From what do you derive that guarantee?
>>
>> The standard guarantees it. "shall ... within its resource limits ...
>> correctly execute that program".
>>
>> When the resource requirements are known at compile time, there is no
>> question about it: if the program loads, and the provided resources are
>> sufficient for those known requirements, it will execute correctly.
>>
> 
> The resource requirements most certainly are /not/ known at compile time
> in general.

What matters is that there are cases where the resource requirements are 
known at compile time.

Those cases happen to include Tim's example.

The programming-in-general case is irrelevant for Tim's case, which 
reduces to the absurd conclusion that no provably correct C++ program 
can be made.


[snipalot associatively suggestive irrelevancies]

>> In practice, as you know, that's done by specifying the minimum stack
>> size in the build of the program, which ensures that it either loads and
>> runs correctly, or else fails to load.
> 
> That might be true in very limited practice.  But you can't extrapolate
> from experience of one Windows compiler and a misunderstanding of the
> difference between a compiler and a linker, and assume it applies "in
> practice" for other cases.

What misunderstanding of compiler and linker? What experience limited to 
one Windows compiler?

Those are social arguments, arguing someone's extreme incompetence about 
the very basics of tool use, in direct contradiction with what you know 
about that person, and arguing someone's very limited experience of 
platforms and compilers, also in direct contradiction with what you 
know. Two untruths that you know are untrue, which means that you 
intentionally lie. And they're presented as an ad hominem argument.

Which means that this argumentation you offer is not offered in good 
faith, which means it's FUD.


[snip]

- Alf

[toc] | [prev] | [next] | [standalone]


#67939

FromDavid Brown <david.brown@hesbynett.no>
Date2019-08-25 15:11 +0200
Message-ID<qju1d7$iqu$1@dont-email.me>
In reply to#67935
On 25/08/2019 13:25, Alf P. Steinbach wrote:
> On 25.08.2019 12:06, David Brown wrote:
>> On 24/08/2019 06:45, Alf P. Steinbach wrote:
>>> On 24.08.2019 01:49, James Kuyper wrote:
>>>> On 8/23/19 5:07 PM, Alf P. Steinbach wrote:
>>>>> On 23.08.2019 16:37, David Brown wrote:
>>>>>> On 23/08/2019 15:28, James Kuyper wrote:
>>>> ...
>>
>>>> It doesn't change the observable behavior. Stack usage isn't
>>>> observable.
>>>> The observable behavior won't occur at all if the program runs out of
>>>> stack space, but that's also a possibility for the iterative version of
>>>> the program, so it doesn't count as a difference in the observable
>>>> behavior.
>>>>
>>>>> With the original code one is guaranteed that it will complete.
>>>>
>>>>   From what do you derive that guarantee?
>>>
>>> The standard guarantees it. "shall ... within its resource limits ...
>>> correctly execute that program".
>>>
>>> When the resource requirements are known at compile time, there is no
>>> question about it: if the program loads, and the provided resources are
>>> sufficient for those known requirements, it will execute correctly.
>>>
>>
>> The resource requirements most certainly are /not/ known at compile time
>> in general.
> 
> What matters is that there are cases where the resource requirements are
> known at compile time.

For programs, rather than particular functions or parts of a program,
those cases are negligible outside of specialist cases in
high-reliability embedded programming.  Agreed?

> 
> Those cases happen to include Tim's example.

True.  That applies to both the recursive and iterative versions of his
code.

> 
> The programming-in-general case is irrelevant for Tim's case, which
> reduces to the absurd conclusion that no provably correct C++ program
> can be made.
> 

In general, you can't prove that C++ programs are correct.  It is, I
would think, very rare when you can do so.  And even then the proof is
dependent and qualified - a program may be proven "correct for
conforming compilers", "correct for provably correct cpus (good luck
finding one)", and so on.

Provably correct programming is important - it forms a theoretical basis
on which practical work can be done.  But it doesn't happen much in real
coding - it requires far too much detail, and far too many restrictions
and limitations for most work.

> 
> [snipalot associatively suggestive irrelevancies]
> 
>>> In practice, as you know, that's done by specifying the minimum stack
>>> size in the build of the program, which ensures that it either loads and
>>> runs correctly, or else fails to load.
>>
>> That might be true in very limited practice.  But you can't extrapolate
>> from experience of one Windows compiler and a misunderstanding of the
>> difference between a compiler and a linker, and assume it applies "in
>> practice" for other cases.
> 
> What misunderstanding of compiler and linker? What experience limited to
> one Windows compiler?

Compilers do not know anything about stack size - at least, not for any
part involved in supporting the standard language.  Information about
stack size is sometimes given to linkers, which can then be put in
OS-specific program headers or used during the linking process to make
the information available to the program.

And in many programs, on many systems, you don't specify the stack size
during build - you get the default for the system executing the program.

In Linux, for example, the default stack size is set by the environment
executing the program (and can be changed by the user).  A running
program can also extend its own size at run time.  There is no (AFAIK)
equivalent of the Windows PE header information about the required stack
size that could be set at link time.

On small embedded systems, you regularly set a desired stack size via
the linker, but never IME via the compiler.  Equally regularly, your
stack size is simply from the top of ram working downwards until it hits
the heap growing upwards.

> 
> Those are social arguments, arguing someone's extreme incompetence about
> the very basics of tool use, in direct contradiction with what you know
> about that person, and arguing someone's very limited experience of
> platforms and compilers, also in direct contradiction with what you
> know. Two untruths that you know are untrue, which means that you
> intentionally lie. And they're presented as an ad hominem argument.

Show me how the minimum stack size is set during build time with a range
of toolchains targetting a range of OS's, including "bare metal".
Otherwise, I believe you are extrapolating from limited experience.

There is nothing ad hominem about that - it is a statement of how your
claims appear.  There is also nothing ad hominem about saying your posts
look like your experience here is highly focused on one platform, and
probably only one compiler.  There is no suggestion that this makes you
a poorer programmer, or less competent - merely that it might be why you
are wrong about this point.

> 
> Which means that this argumentation you offer is not offered in good
> faith, which means it's FUD.
> 

Cut down on the paranoia, and you'll enjoy these discussions more.

[toc] | [prev] | [next] | [standalone]


#67945

From"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>
Date2019-08-25 17:12 +0200
Message-ID<qju8ho$pmq$1@dont-email.me>
In reply to#67939
On 25.08.2019 15:11, David Brown wrote:
> On 25/08/2019 13:25, Alf P. Steinbach wrote:
>> On 25.08.2019 12:06, David Brown wrote:
>>> On 24/08/2019 06:45, Alf P. Steinbach wrote:
>>>> On 24.08.2019 01:49, James Kuyper wrote:
>>>>> On 8/23/19 5:07 PM, Alf P. Steinbach wrote:
>>>>>> On 23.08.2019 16:37, David Brown wrote:
>>>>>>> On 23/08/2019 15:28, James Kuyper wrote:
>>>>> ...
>>>
>>>>> It doesn't change the observable behavior. Stack usage isn't
>>>>> observable.
>>>>> The observable behavior won't occur at all if the program runs out of
>>>>> stack space, but that's also a possibility for the iterative version of
>>>>> the program, so it doesn't count as a difference in the observable
>>>>> behavior.
>>>>>
>>>>>> With the original code one is guaranteed that it will complete.
>>>>>
>>>>>    From what do you derive that guarantee?
>>>>
>>>> The standard guarantees it. "shall ... within its resource limits ...
>>>> correctly execute that program".
>>>>
>>>> When the resource requirements are known at compile time, there is no
>>>> question about it: if the program loads, and the provided resources are
>>>> sufficient for those known requirements, it will execute correctly.
>>>>
>>>
>>> The resource requirements most certainly are /not/ known at compile time
>>> in general.
>>
>> What matters is that there are cases where the resource requirements are
>> known at compile time.
> 
> For programs, rather than particular functions or parts of a program,
> those cases are negligible outside of specialist cases in
> high-reliability embedded programming.  Agreed?
> 
>>
>> Those cases happen to include Tim's example.
> 
> True.  That applies to both the recursive and iterative versions of his
> code.
> 
>>
>> The programming-in-general case is irrelevant for Tim's case, which
>> reduces to the absurd conclusion that no provably correct C++ program
>> can be made.
>>
> 
> In general, you can't prove that C++ programs are correct.  It is, I
> would think, very rare when you can do so.  And even then the proof is
> dependent and qualified - a program may be proven "correct for
> conforming compilers", "correct for provably correct cpus (good luck
> finding one)", and so on.
> 
> Provably correct programming is important - it forms a theoretical basis
> on which practical work can be done.  But it doesn't happen much in real
> coding - it requires far too much detail, and far too many restrictions
> and limitations for most work.
> 
>>
>> [snipalot associatively suggestive irrelevancies]
>>
>>>> In practice, as you know, that's done by specifying the minimum stack
>>>> size in the build of the program, which ensures that it either loads and
>>>> runs correctly, or else fails to load.
>>>
>>> That might be true in very limited practice.  But you can't extrapolate
>>> from experience of one Windows compiler and a misunderstanding of the
>>> difference between a compiler and a linker, and assume it applies "in
>>> practice" for other cases.
>>
>> What misunderstanding of compiler and linker? What experience limited to
>> one Windows compiler?
> 
> Compilers do not know anything about stack size - at least, not for any
> part involved in supporting the standard language.

A compiler does know the size of a function's stack frame. It usually 
emits instructions to adjust the stack pointer, as part of establishing 
the frame, in the function prolog. So any C++ compiler knows a bit about 
the stack size.

I think you meant something else than what you literally wrote.

But then, your argumentation against me has been about what I literally 
wrote, with a bit of context removed.


> Information about
> stack size is sometimes given to linkers,

That's true, just as it would be true to say that it's sometimes given 
to the compiler, which is often how the linker is invoked in C++. 
Especially with g++ it's just too dang impractical to invoke ld directly 
for linking of C++ code. One lets the front-end g++ do the job of 
applying the requisite options for C++ linking.

I can't recall saying that a stack size option should be given to the 
compiler, or to the linker, and you did not quote any such statement; 
instead you quoted me writing "in the build". Which means you're again 
trying to convey an impression that you know is false.

Which, again, is called lying.

Anyway your idea that such an option can only be given to the linker is 
incorrect, and I know that you know that that is incorrect. With Visual 
C++ the compiler option to set stack size is `/F<n>`. With g++ (and 
hence clang) it can apparently only be given as a linker option, as 
`--stack <n>`. But it can be given to the compiler, which forwards it, 
as any linker option can, as `-Wl,--stack,<n>`, which for C++ would be 
the preferred way due to raw use of `ld` being impractical.

Even if like me you don't go around remembering the specific options, 
you're not an inexperienced novice that doesn't know about the basic 
tool usage, so also this was a lie.

And again, I didn't specify how to do it, or using which of compiler and 
linker: that would be in your fantasy, if you /believed/ what you wrote.


> which can then be put in
> OS-specific program headers or used during the linking process to make
> the information available to the program. 
> > And in many programs, on many systems, you don't specify the stack size
> during build - you get the default for the system executing the program.
> 
> In Linux, for example, the default stack size is set by the environment
> executing the program (and can be changed by the user).  A running
> program can also extend its own size at run time.  There is no (AFAIK)
> equivalent of the Windows PE header information about the required stack
> size that could be set at link time.

Yes, that's right, I failed to think of that. I've never needed to do 
that. But then I continued, which you snipped,

"But conceivably it could be done in other ways, even for each 
execution. However it's done, when a fixed resource requirements program 
produced by a conforming compiler is run, it produces a correct result."

As I see it, "However it's done" covers the Linux way.

It's a little imperfection that you could have noted with fact, instead 
of spewing out a series of personal lies.


> [snip]
>> Which means that this argumentation you offer is not offered in good
>> faith, which means it's FUD.
>>
> 
> Cut down on the paranoia, and you'll enjoy these discussions more.

I decided some years ago to not let people get away with provable lies.

So I prove them.

That's not paranoia, and you know it.


Cheers,

- Alf

[toc] | [prev] | [next] | [standalone]


#67948

FromDavid Brown <david.brown@hesbynett.no>
Date2019-08-25 23:32 +0200
Message-ID<qjuuph$pam$1@dont-email.me>
In reply to#67945
On 25/08/2019 17:12, Alf P. Steinbach wrote:
> On 25.08.2019 15:11, David Brown wrote:
>> On 25/08/2019 13:25, Alf P. Steinbach wrote:
>>> On 25.08.2019 12:06, David Brown wrote:
>>>> On 24/08/2019 06:45, Alf P. Steinbach wrote:
>>>>> On 24.08.2019 01:49, James Kuyper wrote:
>>>>>> On 8/23/19 5:07 PM, Alf P. Steinbach wrote:
>>>>>>> On 23.08.2019 16:37, David Brown wrote:
>>>>>>>> On 23/08/2019 15:28, James Kuyper wrote:
>>>>>> ...
>>>>
>>>>>> It doesn't change the observable behavior. Stack usage isn't
>>>>>> observable.
>>>>>> The observable behavior won't occur at all if the program runs out of
>>>>>> stack space, but that's also a possibility for the iterative 
>>>>>> version of
>>>>>> the program, so it doesn't count as a difference in the observable
>>>>>> behavior.
>>>>>>
>>>>>>> With the original code one is guaranteed that it will complete.
>>>>>>
>>>>>>    From what do you derive that guarantee?
>>>>>
>>>>> The standard guarantees it. "shall ... within its resource limits ...
>>>>> correctly execute that program".
>>>>>
>>>>> When the resource requirements are known at compile time, there is no
>>>>> question about it: if the program loads, and the provided resources 
>>>>> are
>>>>> sufficient for those known requirements, it will execute correctly.
>>>>>
>>>>
>>>> The resource requirements most certainly are /not/ known at compile 
>>>> time
>>>> in general.
>>>
>>> What matters is that there are cases where the resource requirements are
>>> known at compile time.
>>
>> For programs, rather than particular functions or parts of a program,
>> those cases are negligible outside of specialist cases in
>> high-reliability embedded programming.  Agreed?
>>
>>>
>>> Those cases happen to include Tim's example.
>>
>> True.  That applies to both the recursive and iterative versions of his
>> code.
>>
>>>
>>> The programming-in-general case is irrelevant for Tim's case, which
>>> reduces to the absurd conclusion that no provably correct C++ program
>>> can be made.
>>>
>>
>> In general, you can't prove that C++ programs are correct.  It is, I
>> would think, very rare when you can do so.  And even then the proof is
>> dependent and qualified - a program may be proven "correct for
>> conforming compilers", "correct for provably correct cpus (good luck
>> finding one)", and so on.
>>
>> Provably correct programming is important - it forms a theoretical basis
>> on which practical work can be done.  But it doesn't happen much in real
>> coding - it requires far too much detail, and far too many restrictions
>> and limitations for most work.
>>
>>>
>>> [snipalot associatively suggestive irrelevancies]
>>>
>>>>> In practice, as you know, that's done by specifying the minimum stack
>>>>> size in the build of the program, which ensures that it either 
>>>>> loads and
>>>>> runs correctly, or else fails to load.
>>>>
>>>> That might be true in very limited practice.  But you can't extrapolate
>>>> from experience of one Windows compiler and a misunderstanding of the
>>>> difference between a compiler and a linker, and assume it applies "in
>>>> practice" for other cases.
>>>
>>> What misunderstanding of compiler and linker? What experience limited to
>>> one Windows compiler?
>>
>> Compilers do not know anything about stack size - at least, not for any
>> part involved in supporting the standard language.
> 
> A compiler does know the size of a function's stack frame. It usually 
> emits instructions to adjust the stack pointer, as part of establishing 
> the frame, in the function prolog. So any C++ compiler knows a bit about 
> the stack size.

Yes, a compiler knows a /bit/ about stack size.  It doesn't know 
everything.  In particular, while it knows about the stack usage within 
most functions, it rarely knows the usage of functions it calls, 
especially if these are outside the current translation unit.  It can't 
know about functions linked at run-time, it rarely has a realistic call 
tree of the functions in the program itself (since call trees are often 
dynamic based on run-time properties), and it hasn't a hope when faced 
with multiple threads, recursion, and call-backs.

> 
> I think you meant something else than what you literally wrote.
> 

I don't think I expressed myself very well.  The standards don't cover 
stack usage at all, in any way.  And for anything outside the program 
code, the compiler hasn't a clue.  (I would be glad if object formats 
/did/ included such information, at least for static linking.)

> But then, your argumentation against me has been about what I literally 
> wrote, with a bit of context removed.
> 
> 
>> Information about
>> stack size is sometimes given to linkers,
> 
> That's true, just as it would be true to say that it's sometimes given 
> to the compiler, which is often how the linker is invoked in C++. 

Until you are talking about link-time optimisation (when the build 
process really gets complicated), the compiler typically does not invoke 
the linker.  (It's not good to be too categoric here - there are many 
ways of organising tools.)

> Especially with g++ it's just too dang impractical to invoke ld directly 
> for linking of C++ code. One lets the front-end g++ do the job of 
> applying the requisite options for C++ linking.

Ah, I see what you are thinking about.  But "g++" (or "gcc") is not the 
compiler.  It is a driver program, that calls the compiler, assembler, 
linker, and other utilities as needed.

> 
> I can't recall saying that a stack size option should be given to the 
> compiler, or to the linker, and you did not quote any such statement; 
> instead you quoted me writing "in the build". Which means you're again 
> trying to convey an impression that you know is false.
> 
> Which, again, is called lying.

No, lying would be making intentionally misleading and false statements. 
  I was certainly under the impression that you had said the stack size 
was given to the compiler - if you didn't, then I made a mistake.

However, you have certainly made claims (unjustified in general) that 
the compiler knows all about stack usage of the code, and that it knows 
if the program's stack usage is within the stack available.  I don't 
know how you expect that to work out if the compiler doesn't know the 
stack size available to the program.

> 
> Anyway your idea that such an option can only be given to the linker is 
> incorrect, and I know that you know that that is incorrect.

I didn't say anything like that.  (But I accuse you of being mistaken, 
not of lying.)  I only said that was a common case, in my experience.

> With Visual 
> C++ the compiler option to set stack size is `/F<n>`. With g++ (and 
> hence clang) it can apparently only be given as a linker option, as 
> `--stack <n>`. But it can be given to the compiler, which forwards it, 
> as any linker option can, as `-Wl,--stack,<n>`, which for C++ would be 
> the preferred way due to raw use of `ld` being impractical.

I don't know how MSVC handles this sort of thing.  But for gcc, you are 
giving the option to the /driver/ program, which passes it on to the 
linker, not the compiler invocation.  (The "-Wl," options are all passed 
to the linker - certain other options are also passed to it.)

My guess - and it is only a guess - is that MSVC has a somewhat similar 
system to gcc regarding the split between a driver program, the 
compiler, and the linker (and assembler, and maybe compilers for other 
languages, and assorted utilities).

> 
> Even if like me you don't go around remembering the specific options, 
> you're not an inexperienced novice that doesn't know about the basic 
> tool usage, so also this was a lie.
> 

I /do/ remember all sorts of specific options - probably more than is 
healthy.  But you were wrong about how gcc and the options work.

Please stop accusing me of lying.  Tell me you think I'm wrong if you 
think that is the case - I get things wrong sometimes.  Tell me if you 
think I've written something stupid or jumbled - I do that too.  But I 
am not lying, which is a different thing altogether.

> And again, I didn't specify how to do it, or using which of compiler and 
> linker: that would be in your fantasy, if you /believed/ what you wrote.
> 
> 
>> which can then be put in
>> OS-specific program headers or used during the linking process to make
>> the information available to the program. > And in many programs, on 
>> many systems, you don't specify the stack size
>> during build - you get the default for the system executing the program.
>>
>> In Linux, for example, the default stack size is set by the environment
>> executing the program (and can be changed by the user).  A running
>> program can also extend its own size at run time.  There is no (AFAIK)
>> equivalent of the Windows PE header information about the required stack
>> size that could be set at link time.
> 
> Yes, that's right, I failed to think of that. I've never needed to do 
> that. But then I continued, which you snipped,
> 
> "But conceivably it could be done in other ways, even for each 
> execution. However it's done, when a fixed resource requirements program 
> produced by a conforming compiler is run, it produces a correct result."
> 
> As I see it, "However it's done" covers the Linux way.

I didn't think it was worth commenting on everything you wrote.

Anyway, neither method in Linux (ulimit by the user, or a run-time call 
within the program) lets the compiler know, at compile time, what stack 
space is available to the program.  (Conceivably, a compiler could take 
a command-line switch for stack size and automatically generate a 
run-time call to request that stack space at the start of main.  I know 
of no such compiler, but it is conceivable.)  And this is all beside the 
point as stack size is not relevant to conformity.

> 
> It's a little imperfection that you could have noted with fact, instead 
> of spewing out a series of personal lies.
> 

If you accuse me of lying again, it will be the end of the discussion.

> 
>> [snip]
>>> Which means that this argumentation you offer is not offered in good
>>> faith, which means it's FUD.
>>>
>>
>> Cut down on the paranoia, and you'll enjoy these discussions more.
> 
> I decided some years ago to not let people get away with provable lies.
> 

When people make mistakes, it can be helpful to correct them (especially 
when the mistakes become a matter of public record).  When people are 
lying, they are usually not worth bothering about.

> So I prove them.

You have been factually inaccurate throughout the discussion.

> 
> That's not paranoia, and you know it.
> 

Do you /really/ think people would waste time concocting a web of lies 
and deceits in a technical Usenet thread?  To what purpose?  Do you 
think I (and others whom you also have accused of various types of 
attack) am conducting some sort of personal vendetta against you, 
perhaps to tarnish your reputation on Usenet?  Do you perhaps think I am 
trying to look good by making you look bad?  Do you think I am so 
insecure that I will lie myself into a deeper hole rather than admit to 
being shown to be wrong?  Or do you have some other theory?  Few people 
lie without very good reason - what do you think my reasons are?

Let me give you a clue - you are not /that/ important that anyone would 
bother lying for your sake.

[toc] | [prev] | [next] | [standalone]


#67950

From"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>
Date2019-08-26 11:51 +0200
Message-ID<qk0a3n$n5j$1@dont-email.me>
In reply to#67948
On 25.08.2019 23:32, David Brown wrote:
> Do you /really/ think people would waste time concocting a web of lies 
> and deceits in a technical Usenet thread?

That's proved again and again. Including in this thread.


> To what purpose?

I don't know, because it's apparently irrational. My pet theory is that 
it springs from the basic human instincts, in particular the strongest 
one, that of belonging to and defending a group. But then there is also 
the copy-cat behaviors and other even more unfathomable reasons.


> Do you  think I (and others whom you also have accused of various types of 
> attack) am conducting some sort of personal vendetta against you, 
> perhaps to tarnish your reputation on Usenet?

No, that's not in your nature. I was surprised some weeks ago when I 
first saw this kind of irrationality from you, but that was because it 
didn't have a context. Now there is a context with your innuendo etc. 
forming part of a herd response: first someone in another thread, which 
I don't recall exactly what, then shortly after Tim in this thread 
pointed out that disagreement with his meaningless notion (that you've 
not adopted) mean to think one was smarter than everybody on the 
committee, i.e. that I'm a megalomanicac; then someone else in this 
thread with innuendo that he was afraid to respond to me, i.e. that I'm 
a bully; then you also in this thread asserting that I'm an 
inexperienced novice and that by proving the provable lies of yours, I 
am most likely paranoid.

Even though I don't remember the other-thread first, the upshot from 
this thread is that I'm an inexperienced novice who happens to be a 
megalomaniac paranoid bully.



> Do you perhaps think I am  trying to look good by making you look bad?

You have made yourself look bad, by jumping on the bandwagon.


> Do you think I am so insecure that I will lie myself into a deeper
> hole rather than admit to being shown to be wrong?  Or do you have
> some other theory?  Few people lie without very good reason

That happens to be contrary to established stats.

Most people lie in everyday conversations. The difference is that those 
lies are not necessarily designed to have negative impact for others.

E.g., first google result about that,
<url: 
https://www.eurekalert.org/pub_releases/2002-06/uoma-urf061002.php>, 
"UMass researcher finds most people lie in everyday conversation".


> - what do you think my reasons are?
Given that this has been an avalanche of quite sudden onset, comprising 
at least 4 persons in the "we use C a lot and love gcc" camp using 
strongly negative ad hominem attacks,

I think it's probably connected to a feeling of protecting that group or 
a larger group. Maybe I've insulted some of you, or maybe I was too hard 
against the first person. Something like that.

Anyway I believe it's instinct-driven behavior.


> Let me give you a clue - you are not /that/ important that anyone would 
> bother lying for your sake.

Here you go again, speculating that (1) I think I'm a very important person.

That's on top of the speculations so far that I'm (2) an inexperienced 
(3) novice who is (4) a paranoid (5) megalomaniac.

Have you heard the expression, to “butter the bacon”? :-D
<url: https://www.youtube.com/watch?v=WYns5vR3QuQ>

   * * *

But of course this shows to any reader, e.g. a prospective employer, not 
that I am any of those things, but that I clearly fail to fit in with a 
group of C/C++ (as opposed to pure C++) programmers; that I fail to 
accept a nonsense belief in order to fit in, which is often important in 
Norway; and that I have been subject to the said group's herd exclusion.

Happily that doesn't matter.


Cheers,

- Alf

[toc] | [prev] | [next] | [standalone]


#67951

FromDavid Brown <david.brown@hesbynett.no>
Date2019-08-26 13:26 +0200
Message-ID<qk0fkq$krl$1@dont-email.me>
In reply to#67950
On 26/08/2019 11:51, Alf P. Steinbach wrote:

>> Do you perhaps think I am  trying to look good by making you look bad?
> 
> You have made yourself look bad, by jumping on the bandwagon.
> 

Then I'm jumping off.

I haven't been lying, and I haven't been insulting you or attacking you.
 If you feel that I have, then I think that says more about you than it
does about me.  And since I have no desire to attack or insult you, but
apparently have done so unintentionally when trying to discuss
technicalities of the C++ language and tools, I guess it's better not to
discuss C++ with you.

I am not a "plonker", and will continue to read your posts (sometimes
you write things that are interesting or inspirational to me), and I
might well reply to you in the future.  But for now at least, this
thread is better off ending.


> Happily that doesn't matter.
> 

On that we agree.

[toc] | [prev] | [next] | [standalone]


#67931

FromDavid Brown <david.brown@hesbynett.no>
Date2019-08-25 11:36 +0200
Message-ID<qjtkrh$gd1$1@dont-email.me>
In reply to#67917
On 23/08/2019 23:07, Alf P. Steinbach wrote:
> On 23.08.2019 16:37, David Brown wrote:
>> On 23/08/2019 15:28, James Kuyper wrote:
>>> On 8/23/19 1:22 AM, Alf P. Steinbach wrote:
>>>> On 23.08.2019 00:45, Ben Bacarisse wrote:
>>>>> "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> writes:
>>>>> <cut>
>>>>>> And I don't think you think you're smarter than everybody else in
>>>>>> this
>>>>>> group just for holding an opinion on UB that nobody else here shares.
>>>>>
>>>>> Why do you think no one else shares Tim's opinion?
>>>>
>>>> Because he's been arguing his view for a very long time and nobody's
>>>> supported him.
>>>
>>> I normally try (and often fail) to avoid paying attention to his posts,
>>> because I've found discussions with him to be unproductive - when I
>>> discuss my disagreements with him, we usually both end up wasting a lot
>>> of time failing to convince each other. He's a lot like you in that
>>> regard.
>>>
>>> He has a strong tendency to elevate what he believes to be the
>>> committee's intent to play a larger role in the interpretation of the
>>> standard than I think appropriate. This can be particularly annoying if
>>> I disagree with him about what that intent was.
>>> If the standard's wording is in conflict with (or even simply fails to
>>> clearly express) the committee's intent, then that wording should be
>>> corrected to clearly express that intent - but that discrepancy doesn't
>>> change the meaning of the words that they actually wrote.
>>>
>>> However, he is very knowledgeable about the standard, and he is correct
>>> about the pre-eminence of a program's observable behavior. The
>>> standard's definition of "observable behavior" is not "behavior which
>>> can be observed" - it's far more specific than that:
>>>
>>> "The least requirements on a conforming implementation are:
>>> — Accesses through volatile glvalues are evaluated strictly according to
>>> the rules of the abstract machine.
>>> — At program termination, all data written into files shall be identical
>>> to one of the possible results that
>>> execution of the program according to the abstract semantics would have
>>> produced.
>>> — The input and output dynamics of interactive devices shall take place
>>> in such a fashion that prompting
>>> output is actually delivered before a program waits for input. What
>>> constitutes an interactive device is
>>> implementation-defined.
>>> These collectively are referred to as the observable behavior of the
>>> program. ..." (4.6p7).
>>>
>>> The term "observable behavior" is in italics, an ISO convention
>>> indicating that this sentence is the official definition of that term.
>>> In the context of the C++ standard, that definition overrides any
>>> alternative interpretation that might otherwise seem appropriate.
>>>
>>> Note that the amount of stack space taken up by a program does not
>>> qualify as "observable behavior".
>>>
>>> The standard very explicitly says "The semantic descriptions in this
>>> International Standard define a parameterized nondeterministic abstract
>>> machine. This International Standard places no requirement on the
>>> structure of conforming implementations. In particular, they need not
>>> copy or emulate the structure of the abstract machine. Rather,
>>> conforming implementations are required to emulate (only) the observable
>>> behavior of the abstract machine as explained below." (4.6p1).
>>>
>>> So if the same observable behavior can be achieved by using either an
>>> iterative or a recursive algorithm, an implementation is free to use
>>> either of those algorithms to achieve it, regardless of which algorithm
>>> you actually expressed in your code. The fact that one algorithm runs a
>>> higher risk of running out of stack space than the other imposes no
>>> requirement on the implementation to avoid that risk (or to embrace it,
>>> for that matter).
>>>
>>
>> Since we are expressing opinions - regardless of how much or little they
>> may be worth - I agree with James here.  And as far as I can see, it is
>> the same as Tim has been saying in this regard.
>>
>> Usually, changing an iterative algorithm into a recursive one will be a
>> pessimisation, taking more space and run-time.  So it is highly unlikely
>> for a compiler to do this sort of thing - it would quickly become an
>> unpopular tool.  But it is allowed to do so.
> 
> As an example, rewriting a function with loop that uses a fixed size
> storage known at compile time, to a recursive function that uses storage
> proportional to the function argument, changes the behavior.
> 

Not as far as the language is concerned, no.

For the programmer, many things are important that are not covered by
the language itself.  The same therefore applies to compilers.

But as far as language conformance goes - and that is what we are
discussing, /nothing/ else matters.  It doesn't matter if the compiler
takes 15 years to finish compiling "Hello, world".  It doesn't matter if
it uses 26 MB of ram for that program.  It doesn't matter if it
generates the code as a Turing program and includes a simulator in the
exe file.

> With the original code one is guaranteed that it will complete.
> 

Nonsense.

The C++ standards only describe how the language is interpreted and
certain aspects of the behaviour.  They don't give guarantees about the
environment, resources, timings, etc.

The /compiler/ might give you more guarantees.  The compiler distributor
might guarantee that the compiler will generate sane code or you get
your money back.  (gcc guarantees that if the compiler breaks, you get
to keep both halves.)

But the C++ standards - the only things relevant for conformance - give
no such guarantees.


> With the recursive one one is not guaranteed completion, because for
> large enough values of the parameter it will run out of stack space, an
> implementation limit.
> 
>   * * *
> 
> Essentially the argument about observable behavior is therefore that a
> compiler is formally permitted to change a program that guarantees a
> result if it compiles and loads, into a program that almost guaranteed
> does not produce a correct result.

No.  (You seem to be totally misunderstanding the concepts of observable
behaviour, C++ conformance, and the role of the language standard in
this post.)

The compiler can manipulate the code in any way, preserving the
observable behaviour, without affecting conformity.  Resources don't
come into it - usually the compiler doesn't know the resources either.

It is not unknown, for real, quality compilers, for different choices of
compiler flags to result in programs that work in their target
environment or don't work - while the observable behaviour of the code
on a target with enough resources is unaffected.  This can happen in
many ways in resource-constrained embedded systems - optimisation flag
choices can make the program too big for flash, use too much ram, too
much stack, take too long to run.  But these aspects are usually beyond
the knowledge of the compiler, and are certainly well beyond the scope
of the standards - and therefore irrelevant for conformity.

> 
> That's a perpetuum mobile construction argument. One doesn't necessarily
> know where someone's logic went astray so that they ended up with a
> perpetuum mobile design, but the end result is just not reality: it's
> absurd. Somewhere in that argument there's necessarily something wrong,
> and that's not a QoI issue.
> 
> 
>> In the same way, between "int a = b + c;" and "int d = a * 2;", the
>> compiler is allowed to insert code calculating the first hundred digits
>> of pi - including the stack space needed for the job.
> 
> No, that's not the same way.
> 
> In this example a fixed storage requirement is not changed to a
> requirement of storage depending on a parameter.

I am sure it would not stretch your imagination to adapt the example to
your liking.  The compiler can insert code to calculate "a" digits of pi
between these two statements.  Happy?

> 
> 
>>  It would be an
>> unpopular tool, but this would not affect the observable behaviour and
>> thus it would not affect the conformance of the compiler.
> 
> It would affect observable behavior. One would get wrong results or
> crashes. Instead of with a conforming compiler, correct results.

No.  Please re-read the part of the C++ standard explaining what
"observable behaviour" is in regards to the standards.  It does /not/
mean "behaviour observed by the user".

> 
> 
>> The standards do not impose any requirements on quality of
>> implementation (though they have a few hints here and there) - that is
>> up to the user.
> 
> That's right, but this isn't QoI, it's about correctness.
> 

Yes - I'm correct, and you're wrong :-)

[toc] | [prev] | [next] | [standalone]


#67936

From"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>
Date2019-08-25 13:27 +0200
Message-ID<qjtrb2$hvu$2@dont-email.me>
In reply to#67931
On 25.08.2019 11:36, David Brown wrote:
> On 23/08/2019 23:07, Alf P. Steinbach wrote:
>> On 23.08.2019 16:37, David Brown wrote:
>> [snip]
>>>   It would be an
>>> unpopular tool, but this would not affect the observable behaviour and
>>> thus it would not affect the conformance of the compiler.
>>
>> It would affect observable behavior. One would get wrong results or
>> crashes. Instead of with a conforming compiler, correct results.
> 
> No.  Please re-read the part of the C++ standard explaining what
> "observable behaviour" is in regards to the standards.  It does /not/
> mean "behaviour observed by the user".

In your opinion results are not part of observable behavior.

That means you have defined yourself out of being taken seriously.


Cheers!,

- Alf

[toc] | [prev] | [next] | [standalone]


#67940

FromDavid Brown <david.brown@hesbynett.no>
Date2019-08-25 15:15 +0200
Message-ID<qju1lb$k6h$1@dont-email.me>
In reply to#67936
On 25/08/2019 13:27, Alf P. Steinbach wrote:
> On 25.08.2019 11:36, David Brown wrote:
>> On 23/08/2019 23:07, Alf P. Steinbach wrote:
>>> On 23.08.2019 16:37, David Brown wrote:
>>> [snip]
>>>>   It would be an
>>>> unpopular tool, but this would not affect the observable behaviour and
>>>> thus it would not affect the conformance of the compiler.
>>>
>>> It would affect observable behavior. One would get wrong results or
>>> crashes. Instead of with a conforming compiler, correct results.
>>
>> No.  Please re-read the part of the C++ standard explaining what
>> "observable behaviour" is in regards to the standards.  It does /not/
>> mean "behaviour observed by the user".
> 
> In your opinion results are not part of observable behavior.

It is not /my/ opinion that matters here.  (Personally, I can usually
observe the difference between programs that run as expected, and those
that crash or fail.)  It is the /C++ standard definition/ of "observable
behaviour" that matters.  Nothing else matters for conformity to the
standards.  How can you find that so difficult?

Read 1.9 "Program Execution" of the standards.  (That is the section
number from C++14, I expect it is similar in other versions.)

> 
> That means you have defined yourself out of being taken seriously.
> 

Complain to the C++ standards committee, not me.

[toc] | [prev] | [next] | [standalone]


#67949

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2019-08-26 00:43 -0400
Message-ID<qjvo23$2rb$1@dont-email.me>
In reply to#67936
On 8/25/19 7:27 AM, Alf P. Steinbach wrote:
> On 25.08.2019 11:36, David Brown wrote:
>> On 23/08/2019 23:07, Alf P. Steinbach wrote:
>>> On 23.08.2019 16:37, David Brown wrote:
>>> [snip]
>>>>   It would be an
>>>> unpopular tool, but this would not affect the observable behaviour and
>>>> thus it would not affect the conformance of the compiler.
>>>
>>> It would affect observable behavior. One would get wrong results or
>>> crashes. Instead of with a conforming compiler, correct results.
>>
>> No.  Please re-read the part of the C++ standard explaining what
>> "observable behaviour" is in regards to the standards.  It does /not/
>> mean "behaviour observed by the user".
> 
> In your opinion results are not part of observable behavior.

No, certain kinds of results do qualify as observable behavior. The
problem is not the observable behavior, except insofar as stack usages
does NOT qualify as such. The problem is resource limits, and on systems
which use them, stack is definitely a resource with a finite limit.

Because an implementation is excused from executing programs correctly
when resource limits are exceeded, the requirement that observable
behavior must occur as specified by the standard applies only when
enough resources are available to execute the program. The standard
imposes no requirements on the minimum amount of resources that must be
available, nor on the maximum amount that may be required. In fact, the
standard says nothing at all about the particular resource (stack space)
that is relevant to this thread.

Therefore, the fact that a recursive implementation of a piece of code
may require more resources than an iterative one does not render
translation of iterative code into a recursive implementation
non-conforming. So long as both ways of implementing the code produce
the required observable behavior when sufficient resources are
available, it doesn't matter, as far as standard conformance is
concerned, that the amount of resources required to produce that
behavior is radically different for the two algorithms. That's purely an
issue of QoI, outside the scope of the C++ standard.

It was never intended to be the case that knowing that an implementation
of C++ is fully conforming would be sufficient to ensure that the
implementation is useful for any particular purpose (or indeed, for any
purpose whatsoever). Too many things that are relevant to usefulness are
outside the scope of the C++ standard, starting with the execution time
of C++ code, which is completely unspecified. If you consider the C++
standard to be impractical, that's because it was never intended to be
practical in that sense. You need to also evaluate the Quality of
Implementation (QoI) of a fully conforming implementation before you can
determine whether it's actually useful for anything.

[toc] | [prev] | [next] | [standalone]


#67925

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2019-08-24 04:58 -0700
Message-ID<86d0gu22sb.fsf@mailhub.linuxsc.com>
In reply to#67898
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> writes:

> The thread has been civilized so far, but now (1) Tim has added a
> social silly-argument (that to disagree with him one must think of
> oneself as smarter than all people on the committee),

You have misunderstood me.  My comment had nothing to do with
whether you agree (or disagree) with me.

I haven't had a chance yet to go through in detail the cascade of
messages following my posting upthread, but I thought I should
correct this misunderstanding right away.

[toc] | [prev] | [next] | [standalone]


Page 2 of 3 — ← Prev page 1 [2] 3  Next page →

Back to top | Article view | comp.lang.c++


csiph-web