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


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

GCC hasn't even gotten around to sequencing argument evaluation yet???

Started byAndrey Tarasevich <andreytarasevich@hotmail.com>
First post2022-04-01 20:34 -0700
Last post2022-04-11 15:11 -0700
Articles 20 on this page of 121 — 25 participants

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


Contents

  GCC hasn't even gotten around to sequencing argument evaluation yet??? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-04-01 20:34 -0700
    Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-04-02 10:19 +0200
      Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Bo Persson <bo@bo-persson.se> - 2022-04-02 12:19 +0200
      Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-02 14:18 +0200
    Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Christian Gollwitzer <auriocus@gmx.de> - 2022-04-02 12:30 +0200
      Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? David Brown <david.brown@hesbynett.no> - 2022-04-02 14:12 +0200
        Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-02 14:20 +0200
        Re: GCC hasn't even gotten around to sequencing argument evaluation Muttley@dastardlyhq.com - 2022-04-02 14:28 +0000
          Re: GCC hasn't even gotten around to sequencing argument evaluation David Brown <david.brown@hesbynett.no> - 2022-04-02 17:27 +0200
            Re: GCC hasn't even gotten around to sequencing argument evaluation Muttley@dastardlyhq.com - 2022-04-02 15:39 +0000
              Re: GCC hasn't even gotten around to sequencing argument evaluation Barry Schwarz <schwarzb@delq.com> - 2022-04-02 09:15 -0700
                Re: GCC hasn't even gotten around to sequencing argument evaluation Muttley@dastardlyhq.com - 2022-04-04 08:21 +0000
                  Re: GCC hasn't even gotten around to sequencing argument evaluation David Brown <david.brown@hesbynett.no> - 2022-04-04 12:02 +0200
                    Re: GCC hasn't even gotten around to sequencing argument evaluation Muttley@dastardlyhq.com - 2022-04-04 14:42 +0000
                      Re: GCC hasn't even gotten around to sequencing argument evaluation Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-04-04 08:49 -0700
                        Re: GCC hasn't even gotten around to sequencing argument evaluation Muttley@dastardlyhq.com - 2022-04-05 15:18 +0000
                          Re: GCC hasn't even gotten around to sequencing argument evaluation Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-04-05 08:37 -0700
                            Re: GCC hasn't even gotten around to sequencing argument evaluation Muttley@dastardlyhq.com - 2022-04-05 15:54 +0000
                              Re: GCC hasn't even gotten around to sequencing argument evaluation David Brown <david.brown@hesbynett.no> - 2022-04-06 11:24 +0200
                                Re: GCC hasn't even gotten around to sequencing argument evaluation Juha Nieminen <nospam@thanks.invalid> - 2022-04-06 10:49 +0000
                                  Re: GCC hasn't even gotten around to sequencing argument evaluation David Brown <david.brown@hesbynett.no> - 2022-04-06 18:21 +0200
                                Re: GCC hasn't even gotten around to sequencing argument evaluation Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2022-04-06 15:40 +0100
                                  Re: GCC hasn't even gotten around to sequencing argument evaluation Muttley@dastardlyhq.com - 2022-04-06 15:00 +0000
                                    Re: GCC hasn't even gotten around to sequencing argument evaluation Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2022-04-06 17:03 +0100
                                      Re: GCC hasn't even gotten around to sequencing argument evaluation Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2022-04-06 17:18 +0100
                                      Re: GCC hasn't even gotten around to sequencing argument evaluation Muttley@dastardlyhq.com - 2022-04-07 08:58 +0000
                                        Re: GCC hasn't even gotten around to sequencing argument evaluation James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-04-07 11:01 -0400
                                Re: GCC hasn't even gotten around to sequencing argument evaluation "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-04-06 23:13 +0200
                                  Re: GCC hasn't even gotten around to sequencing argument evaluation David Brown <david.brown@hesbynett.no> - 2022-04-07 09:11 +0200
                              Re: GCC hasn't even gotten around to sequencing argument evaluation Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-04-06 10:53 -0700
                              Re: GCC hasn't even gotten around to sequencing argument evaluation James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-04-06 14:50 -0400
                                Re: GCC hasn't even gotten around to sequencing argument evaluation Sams Lara <samlara622@gmail.com> - 2022-04-06 22:27 +0100
                                  Re: GCC hasn't even gotten around to sequencing argument evaluation Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-04-06 14:51 -0700
                                    Re: GCC hasn't even gotten around to sequencing argument evaluation Sams Lara <samlara622@gmail.com> - 2022-04-06 22:59 +0100
                                      Re: GCC hasn't even gotten around to sequencing argument evaluation Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-04-06 15:54 -0700
                                  Re: GCC hasn't even gotten around to sequencing argument evaluation Öö Tiib <ootiib@hot.ee> - 2022-04-06 15:11 -0700
                                    Re: GCC hasn't even gotten around to sequencing argument evaluation Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-04-09 09:38 -0700
                                  Re: GCC hasn't even gotten around to sequencing argument evaluation James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-04-06 23:48 -0400
                                Re: GCC hasn't even gotten around to sequencing argument evaluation Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-04-06 18:39 -0700
                                  Re: GCC hasn't even gotten around to sequencing argument evaluation James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-04-06 23:49 -0400
                            Re: GCC hasn't even gotten around to sequencing argument evaluation Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-04-05 08:55 -0700
                              Re: GCC hasn't even gotten around to sequencing argument evaluation Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-04-05 10:23 -0700
                          Re: GCC hasn't even gotten around to sequencing argument evaluation James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-04-05 14:36 -0400
                      Re: GCC hasn't even gotten around to sequencing argument evaluation James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-04-04 12:27 -0400
                        Re: GCC hasn't even gotten around to sequencing argument evaluation Muttley@dastardlyhq.com - 2022-04-05 15:21 +0000
                          Re: GCC hasn't even gotten around to sequencing argument evaluation Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-04-05 08:41 -0700
                            Re: GCC hasn't even gotten around to sequencing argument evaluation Muttley@dastardlyhq.com - 2022-04-05 15:50 +0000
                              Re: GCC hasn't even gotten around to sequencing argument evaluation Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-04-05 10:19 -0700
                              Re: GCC hasn't even gotten around to sequencing argument evaluation James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-04-05 14:33 -0400
                          Re: GCC hasn't even gotten around to sequencing argument evaluation James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-04-05 14:28 -0400
                      Re: GCC hasn't even gotten around to sequencing argument evaluation David Brown <david.brown@hesbynett.no> - 2022-04-04 18:29 +0200
              Re: GCC hasn't even gotten around to sequencing argument evaluation Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-04-02 11:27 -0700
                Re: GCC hasn't even gotten around to sequencing argument evaluation Muttley@dastardlyhq.com - 2022-04-04 08:23 +0000
                  Re: GCC hasn't even gotten around to sequencing argument evaluation David Brown <david.brown@hesbynett.no> - 2022-04-04 12:15 +0200
                    Re: GCC hasn't even gotten around to sequencing argument evaluation Muttley@dastardlyhq.com - 2022-04-04 14:43 +0000
                      Re: GCC hasn't even gotten around to sequencing argument evaluation David Brown <david.brown@hesbynett.no> - 2022-04-04 18:34 +0200
                        Re: GCC hasn't even gotten around to sequencing argument evaluation Muttley@dastardlyhq.com - 2022-04-05 15:23 +0000
                          Re: GCC hasn't even gotten around to sequencing argument evaluation Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-04-05 08:38 -0700
                            Re: GCC hasn't even gotten around to sequencing argument evaluation Muttley@dastardlyhq.com - 2022-04-05 15:49 +0000
                              Re: GCC hasn't even gotten around to sequencing argument evaluation Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-04-05 11:31 -0700
                                Re: GCC hasn't even gotten around to sequencing argument evaluation scott@slp53.sl.home (Scott Lurndal) - 2022-04-05 22:45 +0000
              Re: GCC hasn't even gotten around to sequencing argument evaluation James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-04-02 23:34 -0400
                Re: GCC hasn't even gotten around to sequencing argument evaluation Manfred <noname@add.invalid> - 2022-04-03 17:43 +0200
                  Re: GCC hasn't even gotten around to sequencing argument evaluation James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-04-03 15:40 -0400
                Re: GCC hasn't even gotten around to sequencing argument evaluation Muttley@dastardlyhq.com - 2022-04-04 08:24 +0000
                  Re: GCC hasn't even gotten around to sequencing argument evaluation James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-04-04 12:01 -0400
              Re: GCC hasn't even gotten around to sequencing argument evaluation David Brown <david.brown@hesbynett.no> - 2022-04-03 13:02 +0200
                Re: GCC hasn't even gotten around to sequencing argument evaluation Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-04-03 04:46 -0700
                  Re: GCC hasn't even gotten around to sequencing argument evaluation Öö Tiib <ootiib@hot.ee> - 2022-04-03 07:02 -0700
                    Re: GCC hasn't even gotten around to sequencing argument evaluation Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-04-03 11:30 -0700
                      Re: GCC hasn't even gotten around to sequencing argument evaluation David Brown <david.brown@hesbynett.no> - 2022-04-03 21:20 +0200
                        Re: GCC hasn't even gotten around to sequencing argument evaluation Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-04-03 12:49 -0700
                          Re: GCC hasn't even gotten around to sequencing argument evaluation Paavo Helde <eesnimi@osa.pri.ee> - 2022-04-04 00:40 +0300
                            Re: GCC hasn't even gotten around to sequencing argument evaluation Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-04-03 15:40 -0700
                              Re: GCC hasn't even gotten around to sequencing argument evaluation David Brown <david.brown@hesbynett.no> - 2022-04-04 09:13 +0200
                          Re: GCC hasn't even gotten around to sequencing argument evaluation David Brown <david.brown@hesbynett.no> - 2022-04-04 09:02 +0200
                            Re: GCC hasn't even gotten around to sequencing argument evaluation Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-04-04 02:07 -0700
                              Re: GCC hasn't even gotten around to sequencing argument evaluation David Brown <david.brown@hesbynett.no> - 2022-04-04 13:28 +0200
                                Re: GCC hasn't even gotten around to sequencing argument evaluation Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-04-04 06:01 -0700
                                  Re: GCC hasn't even gotten around to sequencing argument evaluation David Brown <david.brown@hesbynett.no> - 2022-04-04 19:11 +0200
                                    Re: GCC hasn't even gotten around to sequencing argument evaluation scott@slp53.sl.home (Scott Lurndal) - 2022-04-04 17:59 +0000
                                      Re: GCC hasn't even gotten around to sequencing argument evaluation Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-04-05 06:55 -0700
                Re: GCC hasn't even gotten around to sequencing argument evaluation Manfred <noname@add.invalid> - 2022-04-03 18:39 +0200
          Re: GCC hasn't even gotten around to sequencing argument evaluation Paavo Helde <eesnimi@osa.pri.ee> - 2022-04-03 09:09 +0300
        Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Manfred <noname@add.invalid> - 2022-04-02 19:53 +0200
          Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? David Brown <david.brown@hesbynett.no> - 2022-04-03 13:45 +0200
            Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Manfred <noname@add.invalid> - 2022-04-03 17:27 +0200
        Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-04-02 21:17 +0100
          Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Manfred <noname@invalid.add> - 2022-04-02 23:04 +0200
            Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-04-03 00:22 +0100
          Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-04-02 17:33 -0700
            Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-04-03 14:23 +0100
            Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-04-06 08:31 -0700
              Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-04-06 11:05 -0700
                Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-04-25 03:32 -0700
      Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-04-02 11:18 -0700
    Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? David Brown <david.brown@hesbynett.no> - 2022-04-02 13:11 +0200
    Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Manu Raju <MR@invalid.invalid> - 2022-04-02 18:26 +0100
    Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Manu Raju <MR@invalid.invalid> - 2022-04-02 21:46 +0100
      Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-04-02 17:35 -0700
    Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Language Lawyer <language.lawyer@gmail.com> - 2022-04-04 02:28 -0700
      Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-04-04 05:52 -0700
        Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Language Lawyer <language.lawyer@gmail.com> - 2022-06-21 03:36 -0700
    Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Juha Nieminen <nospam@thanks.invalid> - 2022-04-04 10:48 +0000
      Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-04-04 05:49 -0700
        Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Juha Nieminen <nospam@thanks.invalid> - 2022-04-05 06:34 +0000
          Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-04-05 10:20 +0100
          Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-04-05 07:51 -0700
            Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Manfred <noname@add.invalid> - 2022-04-05 17:53 +0200
    Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Christian Hanné <the.hanne@gmail.com> - 2022-04-10 06:06 +0200
      Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-04-09 21:20 -0700
      Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> - 2022-04-09 21:39 -0700
        Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-04-09 22:34 -0700
          Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Christian Hanné <the.hanne@gmail.com> - 2022-04-10 09:19 +0200
            Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? David Brown <david.brown@hesbynett.no> - 2022-04-10 12:21 +0200
              Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Christian Hanné <the.hanne@gmail.com> - 2022-04-10 12:47 +0200
            Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> - 2022-04-11 12:18 -0700
              Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-04-11 12:33 -0700
        Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Christian Hanné <the.hanne@gmail.com> - 2022-04-10 09:20 +0200
          Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> - 2022-04-11 12:32 -0700
            Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-04-11 15:11 -0700

Page 4 of 7 — ← Prev page 1 2 3 [4] 5 6 7  Next page →


#83494 — Re: GCC hasn't even gotten around to sequencing argument evaluation

Fromscott@slp53.sl.home (Scott Lurndal)
Date2022-04-05 22:45 +0000
SubjectRe: GCC hasn't even gotten around to sequencing argument evaluation
Message-ID<TD33K.210663$OT%7.1445@fx07.iad>
In reply to#83489
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>Muttley@dastardlyhq.com writes:
>> On Tue, 5 Apr 2022 08:38:16 -0700
>> Andrey Tarasevich <andreytarasevich@hotmail.com> wrote:
>>>On 4/5/2022 8:23 AM, Muttley@dastardlyhq.com wrote:

>>>"Test programs" don't demonstrate anything at all.
>>
>> So how would you demonstrate how a compiler treats some code then? Ask it?
>>
>> int main()
>> {
>> 	int i = 0;
>> 	i = i++ + ++i;
>> 	printf("%d\n",i);
>> 	return 0;
>> }
>>
>> The output with clang is 1, 2 with gcc. If what you said was correct the
>> result would be 0, an abort or some kind of compilation error.
>
>We're talking about what the standard *allows* compilers to do, whether
>any actual compiler takes advantage of that permission or not.
>
>The statement was that a compiler *can* replace `i = i++ + ++i;`
>with `__builtin_unreachable()`, not that it *must*.

And in any case, the 6 line program above doesn't exercise any
of the more sophisticated parts of the compiler.  Include that
fragment in a 4000 line source file, add -O3, and who know what code it
may generate differently.

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


#83428 — Re: GCC hasn't even gotten around to sequencing argument evaluation

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2022-04-02 23:34 -0400
SubjectRe: GCC hasn't even gotten around to sequencing argument evaluation
Message-ID<t2b4k4$19d$1@dont-email.me>
In reply to#83416
On 4/2/22 11:39, Muttley@dastardlyhq.com wrote:
...
> Undefined simply means no one cared enough to define it.

"undefined behavior
behavior, upon use of a nonportable or erroneous program construct or of
erroneous data, for which this document imposes no requirements" (3.4.3p1).

Key point so pay attention to:
1. It's undefined if "this document" (the C standard) imposes no
requirements, even if some other document does impose requirements.
2. "No requirements" is far stronger than most people think, the
standard tries to make this clear with some examples:

"Possible undefined behavior ranges from ignoring the situation
completely with unpredictable results, to behaving during translation or
program execution in a documented manner characteristic of the
environment (with or without the issuance of a diagnostic message), to
terminating a translation or execution (with the issuance of a
diagnostic message)." (3.4.3p2)

Notice that undefined behavior can occur before the program even
executes, at compile time. The general rule is that, as soon as it would
otherwise become inevitable that code with undefined behavior would get
executed, the C standard ceases to impose any requirements on the
behavior of your program. This might occur LONG before that code gets
executed, and might have a consequence of not actually executing that code.

The standard also tell you how you can identify whether the behavior is
undefined:

"If a "shall" or "shall not" requirement that appears outside of a
constraint or runtime-constraint is violated, the behavior is undefined.
Undefined behavior is otherwise indicated in this document by the words
"undefined behavior" or by the omission of any explicit definition of
behavior. There is no difference in emphasis among these three; they all
describe "behavior that is undefined"." (4p2).

> The compiler writers
> would have to deliberately change their parameter parsing and stack pushing
> code in order to crash in this instance.

The most common way that undefined behavior has consequences is when it
enables an implementation to simplify an optimization, by not bothering
to worry about whether code might be written which has undefined
behavior. This means that the consequences of code with undefined
behavior can occur in places far removed from that code.

A famous example has the following structure:

if(p==NULL)
{
   printf("p is null\n");
}
*p = 0;

Because the "*p = 0" expression would have undefined behavior if p were
NULL, then an implementation is free to assume that p is NOT null. As a
result, a fully conforming implementation of C can drop the the entire
if-statement - and this is an optimization that real compilers have
actually implemented.

>> POSIX, documented compiler features, etc.), then you can't rely on it
>> for any purpose.
> 
> You can't rely on a rusty bicycle working, but its not going to shoot you in
> the head.

The ways in which real-world fully conforming implementations of C can
handle code with undefined behavior are much weirder and far harder to
predict than the ways a rusty bicycle can fail.

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


#83436 — Re: GCC hasn't even gotten around to sequencing argument evaluation

FromManfred <noname@add.invalid>
Date2022-04-03 17:43 +0200
SubjectRe: GCC hasn't even gotten around to sequencing argument evaluation
Message-ID<t2cfbg$18rh$1@gioia.aioe.org>
In reply to#83428
On 4/3/2022 5:34 AM, James Kuyper wrote:
> On 4/2/22 11:39, Muttley@dastardlyhq.com wrote:
> ...
>> Undefined simply means no one cared enough to define it.
> 
> "undefined behavior
> behavior, upon use of a nonportable or erroneous program construct or of
> erroneous data, for which this document imposes no requirements" (3.4.3p1).

Note that this is the definition in the C standard. The C++ standard 
(since we're in c.l.c++) makes it more abrupt (n4659, 3.27):
   "undefined behavior
    behavior for which this International Standard imposes no requirements"

Followed by a note containing a plethora of sentences arguably hardly 
clarifying anything (IMO)

 > [...]

However, your conclusion is right:

> 
> The ways in which real-world fully conforming implementations of C can
> handle code with undefined behavior are much weirder and far harder to
> predict than the ways a rusty bicycle can fail.
> 

In short: if your program is supposed to work, you need to ensure that 
it never runs into undefined behavior. Never.

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


#83441 — Re: GCC hasn't even gotten around to sequencing argument evaluation

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2022-04-03 15:40 -0400
SubjectRe: GCC hasn't even gotten around to sequencing argument evaluation
Message-ID<t2ct70$vr2$1@dont-email.me>
In reply to#83436
On 4/3/22 11:43, Manfred wrote:
> On 4/3/2022 5:34 AM, James Kuyper wrote:
>> On 4/2/22 11:39, Muttley@dastardlyhq.com wrote:
>> ...
>>> Undefined simply means no one cared enough to define it.
>>
>> "undefined behavior
>> behavior, upon use of a nonportable or erroneous program construct or of
>> erroneous data, for which this document imposes no requirements" (3.4.3p1).
> 
> Note that this is the definition in the C standard. The C++ standard 
> (since we're in c.l.c++) makes it more abrupt (n4659, 3.27):

My apologies - I reference both standards frequently enough that I
sometimes grab the wrong one.

...
>> The ways in which real-world fully conforming implementations of C can
>> handle code with undefined behavior are much weirder and far harder to
>> predict than the ways a rusty bicycle can fail.
>>
> 
> In short: if your program is supposed to work, you need to ensure that 
> it never runs into undefined behavior. Never.


I wouldn't put it that strongly - one of the key reasons why many things
have undefined behavior is that it enables extensions to C++. If the
behavior is undefined by the C++ standard, but defined by some other
document (such as POSIX, or your implementation's documentation),
there's no problem with writing code they relies upon what it says in
that other document, so long as that document has authority over all of
the systems where you will need it.
But make sure that there actually is such a document, and make sure that
you know what it actually says.
The example I gave was due to people thinking that the documented
behavior of dereferencing a null pointer was to safely retrieve whatever
was stored at memory address 0, since that's what the hardware does. But
C is NOT an assembler. It's not the hardware's definition of the
behavior that's relevant, it's the compiler's, and the compiler
documented that the behavior of dereferencing a pointer (of any value,
null or not) was to enable optimizations based upon the assumption that
the pointer could not be null. This optimization was optional, and the
people who wrote that code had the option turned on.

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


#83451 — Re: GCC hasn't even gotten around to sequencing argument evaluation

FromMuttley@dastardlyhq.com
Date2022-04-04 08:24 +0000
SubjectRe: GCC hasn't even gotten around to sequencing argument evaluation
Message-ID<t2ea07$sgm$1@gioia.aioe.org>
In reply to#83428
On Sat, 2 Apr 2022 23:34:28 -0400
James Kuyper <jameskuyper@alumni.caltech.edu> wrote:
>On 4/2/22 11:39, Muttley@dastardlyhq.com wrote:
>....
>> Undefined simply means no one cared enough to define it.
>
>"undefined behavior
>behavior, upon use of a nonportable or erroneous program construct or of
>erroneous data, for which this document imposes no requirements" (3.4.3p1).
>
>Key point so pay attention to:
>1. It's undefined if "this document" (the C standard) imposes no
>requirements, even if some other document does impose requirements.

How does that differ to what I said?

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


#83465 — Re: GCC hasn't even gotten around to sequencing argument evaluation

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2022-04-04 12:01 -0400
SubjectRe: GCC hasn't even gotten around to sequencing argument evaluation
Message-ID<t2f4ol$v7e$1@dont-email.me>
In reply to#83451
On 4/4/22 04:24, Muttley@dastardlyhq.com wrote:
> On Sat, 2 Apr 2022 23:34:28 -0400
> James Kuyper <jameskuyper@alumni.caltech.edu> wrote:
>> On 4/2/22 11:39, Muttley@dastardlyhq.com wrote:
>> ....
>>> Undefined simply means no one cared enough to define it.
>>
>> "undefined behavior
>> behavior, upon use of a nonportable or erroneous program construct or of
>> erroneous data, for which this document imposes no requirements" (3.4.3p1).
>>
>> Key point so pay attention to:
>> 1. It's undefined if "this document" (the C standard) imposes no
>> requirements, even if some other document does impose requirements.
> 
> How does that differ to what I said?
> 

It differs *from* what you said in two key ways:

1. "No one" - It still qualifies as "undefined behavior", as that term
is defined by the standard, even if someone does care enough to define
the behavior, so long as it is defined only by something other than the
standard.

Undefined behavior is often what justifies an extension to C++. The
standard requires that all strictly conforming programs be translated in
a way that conforms to the standard. If there's no way to invoke a given
extension without writing code that has undefined behavior, code that
does invoke it no longer qualifies as strictly conforming code, and an
implementation is therefore free to define the behavior of such code
behavior as implementating that extension.

2. "cares" - in many cases, the committee did care about the behavior,
but decided that the range of behaviors provided by real-world
implementations was too broad to allow the behavior to be merely
"unspecified".

Sometimes the committee says that the behavior is undefined precisely
because they do care. For instance, here's a case that's very similar to
the one under discussion:

"If a side effect on a memory location (6.7.1) is unsequenced relative
to either another side effect on the same memory location or a value
computation using the value of any object in the same memory location,
and they are not potentially concurrent (6.9.2), the behavior is
undefined." (6.9.1p10). An example is given:

    i = i++ + i;	// undefined behavior.

This wasn't made undefined because the committee didn't care to define
the behavior. It was made undefined because the committee cared a great
deal about such code, feeling that it was a bad idea to write such code,
and they made if undefined with the explicit purpose of discouraging the
writing of such code.

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


#83430 — Re: GCC hasn't even gotten around to sequencing argument evaluation

FromDavid Brown <david.brown@hesbynett.no>
Date2022-04-03 13:02 +0200
SubjectRe: GCC hasn't even gotten around to sequencing argument evaluation
Message-ID<t2bust$vaj$1@dont-email.me>
In reply to#83416
On 02/04/2022 17:39, Muttley@dastardlyhq.com wrote:
> On Sat, 2 Apr 2022 17:27:39 +0200
> David Brown <david.brown@hesbynett.no> wrote:
>> On 02/04/2022 16:28, Muttley@dastardlyhq.com wrote:
>>> On Sat, 2 Apr 2022 14:12:17 +0200
>>> David Brown <david.brown@hesbynett.no> wrote:
>>>> It seems gcc has handled this as:
>>>>
>>>> 	++i;
>>>> 	++i;
>>>> 	a = i;
>>>> 	b = i;
>>>>
>>>> and AFAIUI, this interleaving is not allowed in C++17.
>>>>
>>>> Prior to C++17, the code could do anything - segfault, return 42, buy
>>>> you flowers - whatever it liked.
>>>
>>> Why would it segfault? Its simply incrementing values albeit in an 
>>> indeterminate order.
>>>
>>
>>
>> In C++17, the incrementing is indeterminate order.  Prior to that, it is
>> undefined behaviour.  UB /could/ do anything.  If the compiler happens
> 
> Undefined simply means no one cared enough to define it. The compiler writers
> would have to deliberately change their parameter parsing and stack pushing
> code in order to crash in this instance.
> 

That kind of argument works when code can be taken alone in small
snippets, without context.  But real code is rarely alone.  Once things
are going wrong, problems can multiply.

Typically, undefined behaviour means the compiler can take short-cuts.
That might mean "doing the obvious thing", but it might mean getting
strange and inconsistent behaviour.  Given "a = b + c;" using signed int
types, the compiler is likely to generate the assembly code for a two's
complement wrapping addition on most processors.  But if it knows that
"b" and "c" are non-negative, then it also knows that "a" is
non-negative and can use that for optimisation - even if the addition
overflowed and "a" contains a negative number.

>> POSIX, documented compiler features, etc.), then you can't rely on it
>> for any purpose.
> 
> You can't rely on a rusty bicycle working, but its not going to shoot you in
> the head.
> 

The bike won't shoot you - but it could fall apart when you are cycling
down a road, and cars swerving to miss you cause a pile-up with dozens
killed.  Undefined behaviour has no inherent limits to its consequences
- that's why you should work to avoid it.

(And no, despite some people's misunderstandings, this is not due to
overly-enthusiastic optimising compilers or flaws in the language - it
is fundamental to all programming, and fundamental to any kind of error
or mistake in the code.  Different compilers, languages, and programming
styles can influence how the risks build up, but not the principles.)

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


#83432 — Re: GCC hasn't even gotten around to sequencing argument evaluation

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2022-04-03 04:46 -0700
SubjectRe: GCC hasn't even gotten around to sequencing argument evaluation
Message-ID<229baf9c-b7a4-417e-81f3-1ac0351cd00cn@googlegroups.com>
In reply to#83430
On Sunday, 3 April 2022 at 12:03:08 UTC+1, David Brown wrote:
> On 02/04/2022 17:39, Mut...@dastardlyhq.com wrote: 
> > On Sat, 2 Apr 2022 17:27:39 +0200 
> > David Brown <david...@hesbynett.no> wrote: 
> >> On 02/04/2022 16:28, Mut...@dastardlyhq.com wrote: 
> >>> On Sat, 2 Apr 2022 14:12:17 +0200 
> >>> David Brown <david...@hesbynett.no> wrote: 
> >>>> It seems gcc has handled this as: 
> >>>> 
> >>>> ++i; 
> >>>> ++i; 
> >>>> a = i; 
> >>>> b = i; 
> >>>> 
> >>>> and AFAIUI, this interleaving is not allowed in C++17. 
> >>>> 
> >>>> Prior to C++17, the code could do anything - segfault, return 42, buy 
> >>>> you flowers - whatever it liked. 
> >>> 
> >>> Why would it segfault? Its simply incrementing values albeit in an 
> >>> indeterminate order. 
> >>> 
> >> 
> >> 
> >> In C++17, the incrementing is indeterminate order. Prior to that, it is 
> >> undefined behaviour. UB /could/ do anything. If the compiler happens 
> > 
> > Undefined simply means no one cared enough to define it. The compiler writers 
> > would have to deliberately change their parameter parsing and stack pushing 
> > code in order to crash in this instance. 
> >
> That kind of argument works when code can be taken alone in small 
> snippets, without context. But real code is rarely alone. Once things 
> are going wrong, problems can multiply. 
> 
> Typically, undefined behaviour means the compiler can take short-cuts. 
> That might mean "doing the obvious thing", but it might mean getting 
> strange and inconsistent behaviour. Given "a = b + c;" using signed int 
> types, the compiler is likely to generate the assembly code for a two's 
> complement wrapping addition on most processors. But if it knows that 
> "b" and "c" are non-negative, then it also knows that "a" is 
> non-negative and can use that for optimisation - even if the addition 
> overflowed and "a" contains a negative number.
> >> POSIX, documented compiler features, etc.), then you can't rely on it 
> >> for any purpose. 
> > 
> > You can't rely on a rusty bicycle working, but its not going to shoot you in 
> > the head. 
> >
> The bike won't shoot you - but it could fall apart when you are cycling 
> down a road, and cars swerving to miss you cause a pile-up with dozens 
> killed. Undefined behaviour has no inherent limits to its consequences 
> - that's why you should work to avoid it. 
> 
> (And no, despite some people's misunderstandings, this is not due to 
> overly-enthusiastic optimising compilers or flaws in the language - it 
> is fundamental to all programming, and fundamental to any kind of error 
> or mistake in the code. Different compilers, languages, and programming 
> styles can influence how the risks build up, but not the principles.)
>
The central issue is that, for some programs, the worst thing you can do is
terminate. For example a video game. If it crashes the game is ruined.
For other programs, the worst thing you can do is return wrong results.
For example a program doing statistical analysis of scientific data. If it
returns wrong values, errors get into the draft paper, with potentially very
far-reaching consequences. If it crashes, however, that's just a minor 
inconvenience.

So for a video game,  we want arithmetical overflow to wrap, and just hope 
that it causes nothing worse than a transient glitch on screen. For the
analysis program, we want it to terminate with an error message.

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


#83434 — Re: GCC hasn't even gotten around to sequencing argument evaluation

FromÖö Tiib <ootiib@hot.ee>
Date2022-04-03 07:02 -0700
SubjectRe: GCC hasn't even gotten around to sequencing argument evaluation
Message-ID<6a3be9d2-aa61-4a78-adca-b1a43bc4571bn@googlegroups.com>
In reply to#83432
On Sunday, 3 April 2022 at 14:47:06 UTC+3, Malcolm McLean wrote:
> On Sunday, 3 April 2022 at 12:03:08 UTC+1, David Brown wrote: 
> > On 02/04/2022 17:39, Mut...@dastardlyhq.com wrote: 
> > > On Sat, 2 Apr 2022 17:27:39 +0200 
> > > David Brown <david...@hesbynett.no> wrote: 
> > >> On 02/04/2022 16:28, Mut...@dastardlyhq.com wrote: 
> > >>> On Sat, 2 Apr 2022 14:12:17 +0200 
> > >>> David Brown <david...@hesbynett.no> wrote: 
> > >>>> It seems gcc has handled this as: 
> > >>>> 
> > >>>> ++i; 
> > >>>> ++i; 
> > >>>> a = i; 
> > >>>> b = i; 
> > >>>> 
> > >>>> and AFAIUI, this interleaving is not allowed in C++17. 
> > >>>> 
> > >>>> Prior to C++17, the code could do anything - segfault, return 42, buy 
> > >>>> you flowers - whatever it liked. 
> > >>> 
> > >>> Why would it segfault? Its simply incrementing values albeit in an 
> > >>> indeterminate order. 
> > >>> 
> > >> 
> > >> 
> > >> In C++17, the incrementing is indeterminate order. Prior to that, it is 
> > >> undefined behaviour. UB /could/ do anything. If the compiler happens 
> > > 
> > > Undefined simply means no one cared enough to define it. The compiler writers 
> > > would have to deliberately change their parameter parsing and stack pushing 
> > > code in order to crash in this instance. 
> > > 
> > That kind of argument works when code can be taken alone in small 
> > snippets, without context. But real code is rarely alone. Once things 
> > are going wrong, problems can multiply. 
> > 
> > Typically, undefined behaviour means the compiler can take short-cuts. 
> > That might mean "doing the obvious thing", but it might mean getting 
> > strange and inconsistent behaviour. Given "a = b + c;" using signed int 
> > types, the compiler is likely to generate the assembly code for a two's 
> > complement wrapping addition on most processors. But if it knows that 
> > "b" and "c" are non-negative, then it also knows that "a" is 
> > non-negative and can use that for optimisation - even if the addition 
> > overflowed and "a" contains a negative number. 
> > >> POSIX, documented compiler features, etc.), then you can't rely on it 
> > >> for any purpose. 
> > > 
> > > You can't rely on a rusty bicycle working, but its not going to shoot you in 
> > > the head. 
> > > 
> > The bike won't shoot you - but it could fall apart when you are cycling 
> > down a road, and cars swerving to miss you cause a pile-up with dozens 
> > killed. Undefined behaviour has no inherent limits to its consequences 
> > - that's why you should work to avoid it. 
> > 
> > (And no, despite some people's misunderstandings, this is not due to 
> > overly-enthusiastic optimising compilers or flaws in the language - it 
> > is fundamental to all programming, and fundamental to any kind of error 
> > or mistake in the code. Different compilers, languages, and programming 
> > styles can influence how the risks build up, but not the principles.) 
> >
> The central issue is that, for some programs, the worst thing you can do is 
> terminate. For example a video game. If it crashes the game is ruined.

While the program is still in development process and so in hands of
developers and testers then cheapest to track down defect is when program
refuses to compile and next best is runtime crash. It does not matter if it is
for entertainment or for something more serious, what matters is
development cost. 

The theory that game is not ruined when it hangs or turns staggeringly slow,
some dialog is empty, some object turns invisible or disappears,  or some
control does not work is questionable.  It happens most commonly when
development philosophy ignored what I wrote about development cost. 
 
> For other programs, the worst thing you can do is return wrong results. 
> For example a program doing statistical analysis of scientific data. If it 
> returns wrong values, errors get into the draft paper, with potentially very 
> far-reaching consequences. If it crashes, however, that's just a minor 
> inconvenience. 
> 
> So for a video game, we want arithmetical overflow to wrap, and just hope 
> that it causes nothing worse than a transient glitch on screen. For the 
> analysis program, we want it to terminate with an error message.

For both we want to discover it before it reaches users. The only exception
is perhaps vaporware proof of concepts meant to raise funds and never
release ... that is better not to crash it during demo to potential investors.

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


#83439 — Re: GCC hasn't even gotten around to sequencing argument evaluation

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2022-04-03 11:30 -0700
SubjectRe: GCC hasn't even gotten around to sequencing argument evaluation
Message-ID<95132c7f-3131-4fa3-a44a-5a026777144en@googlegroups.com>
In reply to#83434
On Sunday, 3 April 2022 at 15:02:19 UTC+1, Öö Tiib wrote:
> On Sunday, 3 April 2022 at 14:47:06 UTC+3, Malcolm McLean wrote: 
> > On Sunday, 3 April 2022 at 12:03:08 UTC+1, David Brown wrote: 
> > > On 02/04/2022 17:39, Mut...@dastardlyhq.com wrote: 
> > > > On Sat, 2 Apr 2022 17:27:39 +0200 
> > > > David Brown <david...@hesbynett.no> wrote: 
> > > >> On 02/04/2022 16:28, Mut...@dastardlyhq.com wrote: 
> > > >>> On Sat, 2 Apr 2022 14:12:17 +0200 
> > > >>> David Brown <david...@hesbynett.no> wrote: 
> > > >>>> It seems gcc has handled this as: 
> > > >>>> 
> > > >>>> ++i; 
> > > >>>> ++i; 
> > > >>>> a = i; 
> > > >>>> b = i; 
> > > >>>> 
> > > >>>> and AFAIUI, this interleaving is not allowed in C++17. 
> > > >>>> 
> > > >>>> Prior to C++17, the code could do anything - segfault, return 42, buy 
> > > >>>> you flowers - whatever it liked. 
> > > >>> 
> > > >>> Why would it segfault? Its simply incrementing values albeit in an 
> > > >>> indeterminate order. 
> > > >>> 
> > > >> 
> > > >> 
> > > >> In C++17, the incrementing is indeterminate order. Prior to that, it is 
> > > >> undefined behaviour. UB /could/ do anything. If the compiler happens 
> > > > 
> > > > Undefined simply means no one cared enough to define it. The compiler writers 
> > > > would have to deliberately change their parameter parsing and stack pushing 
> > > > code in order to crash in this instance. 
> > > > 
> > > That kind of argument works when code can be taken alone in small 
> > > snippets, without context. But real code is rarely alone. Once things 
> > > are going wrong, problems can multiply. 
> > > 
> > > Typically, undefined behaviour means the compiler can take short-cuts. 
> > > That might mean "doing the obvious thing", but it might mean getting 
> > > strange and inconsistent behaviour. Given "a = b + c;" using signed int 
> > > types, the compiler is likely to generate the assembly code for a two's 
> > > complement wrapping addition on most processors. But if it knows that 
> > > "b" and "c" are non-negative, then it also knows that "a" is 
> > > non-negative and can use that for optimisation - even if the addition 
> > > overflowed and "a" contains a negative number. 
> > > >> POSIX, documented compiler features, etc.), then you can't rely on it 
> > > >> for any purpose. 
> > > > 
> > > > You can't rely on a rusty bicycle working, but its not going to shoot you in 
> > > > the head. 
> > > > 
> > > The bike won't shoot you - but it could fall apart when you are cycling 
> > > down a road, and cars swerving to miss you cause a pile-up with dozens 
> > > killed. Undefined behaviour has no inherent limits to its consequences 
> > > - that's why you should work to avoid it. 
> > > 
> > > (And no, despite some people's misunderstandings, this is not due to 
> > > overly-enthusiastic optimising compilers or flaws in the language - it 
> > > is fundamental to all programming, and fundamental to any kind of error 
> > > or mistake in the code. Different compilers, languages, and programming 
> > > styles can influence how the risks build up, but not the principles.) 
> > > 
> > The central issue is that, for some programs, the worst thing you can do is 
> > terminate. For example a video game. If it crashes the game is ruined.
> While the program is still in development process and so in hands of 
> developers and testers then cheapest to track down defect is when program 
> refuses to compile and next best is runtime crash. It does not matter if it is 
> for entertainment or for something more serious, what matters is 
> development cost. 
>
If you're writing control systems for nuclear reactors, you have to have really
tight quality control, including proving of algorithms. But if you're doing 
everyday programming, you just don't have those resources.

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


#83440 — Re: GCC hasn't even gotten around to sequencing argument evaluation

FromDavid Brown <david.brown@hesbynett.no>
Date2022-04-03 21:20 +0200
SubjectRe: GCC hasn't even gotten around to sequencing argument evaluation
Message-ID<t2cs1l$8t9$1@dont-email.me>
In reply to#83439
On 03/04/2022 20:30, Malcolm McLean wrote:
> On Sunday, 3 April 2022 at 15:02:19 UTC+1, Öö Tiib wrote:
>> On Sunday, 3 April 2022 at 14:47:06 UTC+3, Malcolm McLean wrote: 
>>> On Sunday, 3 April 2022 at 12:03:08 UTC+1, David Brown wrote: 
>>>> On 02/04/2022 17:39, Mut...@dastardlyhq.com wrote: 
>>>>> On Sat, 2 Apr 2022 17:27:39 +0200 
>>>>> David Brown <david...@hesbynett.no> wrote: 
>>>>>> On 02/04/2022 16:28, Mut...@dastardlyhq.com wrote: 
>>>>>>> On Sat, 2 Apr 2022 14:12:17 +0200 
>>>>>>> David Brown <david...@hesbynett.no> wrote: 
>>>>>>>> It seems gcc has handled this as: 
>>>>>>>>
>>>>>>>> ++i; 
>>>>>>>> ++i; 
>>>>>>>> a = i; 
>>>>>>>> b = i; 
>>>>>>>>
>>>>>>>> and AFAIUI, this interleaving is not allowed in C++17. 
>>>>>>>>
>>>>>>>> Prior to C++17, the code could do anything - segfault, return 42, buy 
>>>>>>>> you flowers - whatever it liked. 
>>>>>>>
>>>>>>> Why would it segfault? Its simply incrementing values albeit in an 
>>>>>>> indeterminate order. 
>>>>>>>
>>>>>>
>>>>>>
>>>>>> In C++17, the incrementing is indeterminate order. Prior to that, it is 
>>>>>> undefined behaviour. UB /could/ do anything. If the compiler happens 
>>>>>
>>>>> Undefined simply means no one cared enough to define it. The compiler writers 
>>>>> would have to deliberately change their parameter parsing and stack pushing 
>>>>> code in order to crash in this instance. 
>>>>>
>>>> That kind of argument works when code can be taken alone in small 
>>>> snippets, without context. But real code is rarely alone. Once things 
>>>> are going wrong, problems can multiply. 
>>>>
>>>> Typically, undefined behaviour means the compiler can take short-cuts. 
>>>> That might mean "doing the obvious thing", but it might mean getting 
>>>> strange and inconsistent behaviour. Given "a = b + c;" using signed int 
>>>> types, the compiler is likely to generate the assembly code for a two's 
>>>> complement wrapping addition on most processors. But if it knows that 
>>>> "b" and "c" are non-negative, then it also knows that "a" is 
>>>> non-negative and can use that for optimisation - even if the addition 
>>>> overflowed and "a" contains a negative number. 
>>>>>> POSIX, documented compiler features, etc.), then you can't rely on it 
>>>>>> for any purpose. 
>>>>>
>>>>> You can't rely on a rusty bicycle working, but its not going to shoot you in 
>>>>> the head. 
>>>>>
>>>> The bike won't shoot you - but it could fall apart when you are cycling 
>>>> down a road, and cars swerving to miss you cause a pile-up with dozens 
>>>> killed. Undefined behaviour has no inherent limits to its consequences 
>>>> - that's why you should work to avoid it. 
>>>>
>>>> (And no, despite some people's misunderstandings, this is not due to 
>>>> overly-enthusiastic optimising compilers or flaws in the language - it 
>>>> is fundamental to all programming, and fundamental to any kind of error 
>>>> or mistake in the code. Different compilers, languages, and programming 
>>>> styles can influence how the risks build up, but not the principles.) 
>>>>
>>> The central issue is that, for some programs, the worst thing you can do is 
>>> terminate. For example a video game. If it crashes the game is ruined.
>> While the program is still in development process and so in hands of 
>> developers and testers then cheapest to track down defect is when program 
>> refuses to compile and next best is runtime crash. It does not matter if it is 
>> for entertainment or for something more serious, what matters is 
>> development cost. 
>>
> If you're writing control systems for nuclear reactors, you have to have really
> tight quality control, including proving of algorithms. But if you're doing 
> everyday programming, you just don't have those resources.
> 
> 

You may not have the resources - or the ability - to write bug-free
code.  That does not mean you should consider some kinds of bugs
"acceptable".  And it certainly does not mean that you should consider
some classes of undefined behaviour as "nothing to worry about, really -
there's no need to be careful about integer arithmetic because there's a
good chance no one will complain about the mistake".

I can appreciate if you find an integer overflow bug and you mark it as
low priority in your long list of bugs in the program because it just
causes a visual glitch.

I cannot accept the attitude that you are happy to write knowingly
incorrect code and hope it causes nothing more than a visual glitch.

Ultimately, these two attitudes can lead to the same thing - programs
released even though you know there are bugs in them, because you don't
have the time or resources to fix everything.  Real life is not perfect.
 But there is a very big difference in the philosophies here.

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


#83442 — Re: GCC hasn't even gotten around to sequencing argument evaluation

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2022-04-03 12:49 -0700
SubjectRe: GCC hasn't even gotten around to sequencing argument evaluation
Message-ID<f606600a-d75b-438c-8671-0cadd35bb2d9n@googlegroups.com>
In reply to#83440
On Sunday, 3 April 2022 at 20:20:36 UTC+1, David Brown wrote:
> On 03/04/2022 20:30, Malcolm McLean wrote: 
> > On Sunday, 3 April 2022 at 15:02:19 UTC+1, Öö Tiib wrote: 
> >> On Sunday, 3 April 2022 at 14:47:06 UTC+3, Malcolm McLean wrote: 
> >>> On Sunday, 3 April 2022 at 12:03:08 UTC+1, David Brown wrote: 
> >>>> On 02/04/2022 17:39, Mut...@dastardlyhq.com wrote: 
> >>>>> On Sat, 2 Apr 2022 17:27:39 +0200 
> >>>>> David Brown <david...@hesbynett.no> wrote: 
> >>>>>> On 02/04/2022 16:28, Mut...@dastardlyhq.com wrote: 
> >>>>>>> On Sat, 2 Apr 2022 14:12:17 +0200 
> >>>>>>> David Brown <david...@hesbynett.no> wrote: 
> >>>>>>>> It seems gcc has handled this as: 
> >>>>>>>> 
> >>>>>>>> ++i; 
> >>>>>>>> ++i; 
> >>>>>>>> a = i; 
> >>>>>>>> b = i; 
> >>>>>>>> 
> >>>>>>>> and AFAIUI, this interleaving is not allowed in C++17. 
> >>>>>>>> 
> >>>>>>>> Prior to C++17, the code could do anything - segfault, return 42, buy 
> >>>>>>>> you flowers - whatever it liked. 
> >>>>>>> 
> >>>>>>> Why would it segfault? Its simply incrementing values albeit in an 
> >>>>>>> indeterminate order. 
> >>>>>>> 
> >>>>>> 
> >>>>>> 
> >>>>>> In C++17, the incrementing is indeterminate order. Prior to that, it is 
> >>>>>> undefined behaviour. UB /could/ do anything. If the compiler happens 
> >>>>> 
> >>>>> Undefined simply means no one cared enough to define it. The compiler writers 
> >>>>> would have to deliberately change their parameter parsing and stack pushing 
> >>>>> code in order to crash in this instance. 
> >>>>> 
> >>>> That kind of argument works when code can be taken alone in small 
> >>>> snippets, without context. But real code is rarely alone. Once things 
> >>>> are going wrong, problems can multiply. 
> >>>> 
> >>>> Typically, undefined behaviour means the compiler can take short-cuts. 
> >>>> That might mean "doing the obvious thing", but it might mean getting 
> >>>> strange and inconsistent behaviour. Given "a = b + c;" using signed int 
> >>>> types, the compiler is likely to generate the assembly code for a two's 
> >>>> complement wrapping addition on most processors. But if it knows that 
> >>>> "b" and "c" are non-negative, then it also knows that "a" is 
> >>>> non-negative and can use that for optimisation - even if the addition 
> >>>> overflowed and "a" contains a negative number. 
> >>>>>> POSIX, documented compiler features, etc.), then you can't rely on it 
> >>>>>> for any purpose. 
> >>>>> 
> >>>>> You can't rely on a rusty bicycle working, but its not going to shoot you in 
> >>>>> the head. 
> >>>>> 
> >>>> The bike won't shoot you - but it could fall apart when you are cycling 
> >>>> down a road, and cars swerving to miss you cause a pile-up with dozens 
> >>>> killed. Undefined behaviour has no inherent limits to its consequences 
> >>>> - that's why you should work to avoid it. 
> >>>> 
> >>>> (And no, despite some people's misunderstandings, this is not due to 
> >>>> overly-enthusiastic optimising compilers or flaws in the language - it 
> >>>> is fundamental to all programming, and fundamental to any kind of error 
> >>>> or mistake in the code. Different compilers, languages, and programming 
> >>>> styles can influence how the risks build up, but not the principles.) 
> >>>> 
> >>> The central issue is that, for some programs, the worst thing you can do is 
> >>> terminate. For example a video game. If it crashes the game is ruined. 
> >> While the program is still in development process and so in hands of 
> >> developers and testers then cheapest to track down defect is when program 
> >> refuses to compile and next best is runtime crash. It does not matter if it is 
> >> for entertainment or for something more serious, what matters is 
> >> development cost. 
> >> 
> > If you're writing control systems for nuclear reactors, you have to have really 
> > tight quality control, including proving of algorithms. But if you're doing 
> > everyday programming, you just don't have those resources. 
> > 
> >
> You may not have the resources - or the ability - to write bug-free 
> code. That does not mean you should consider some kinds of bugs 
> "acceptable". And it certainly does not mean that you should consider 
> some classes of undefined behaviour as "nothing to worry about, really - 
> there's no need to be careful about integer arithmetic because there's a 
> good chance no one will complain about the mistake". 
> 
> I can appreciate if you find an integer overflow bug and you mark it as 
> low priority in your long list of bugs in the program because it just 
> causes a visual glitch. 
> 
> I cannot accept the attitude that you are happy to write knowingly 
> incorrect code and hope it causes nothing more than a visual glitch. 
> 
> Ultimately, these two attitudes can lead to the same thing - programs 
> released even though you know there are bugs in them, because you don't 
> have the time or resources to fix everything. Real life is not perfect. 
> But there is a very big difference in the philosophies here.
>
You fail to follow.
Say we have this code.

FILE *fp = openfile();
int width = readinteger(fp);
int height = readinteger(fp);
int Npixels = width * height;  // potential bug here

Now of course we should put in a test before multiplying two integers
from an outside source. But these sorts of errors happen. The question is
that, given that despite all our best efforts this code has got through to
production, how do we want the program to behave?

Should we compile with the option "abort on arithmetic overflow" or
"wrap on arithmetic overflow"?.

As an exercise to the reader, there's a school of thought that these values
should be size_t. What are the consequences of that policy for program
robustness?

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


#83443 — Re: GCC hasn't even gotten around to sequencing argument evaluation

FromPaavo Helde <eesnimi@osa.pri.ee>
Date2022-04-04 00:40 +0300
SubjectRe: GCC hasn't even gotten around to sequencing argument evaluation
Message-ID<t2d48q$bvt$1@dont-email.me>
In reply to#83442
03.04.2022 22:49 Malcolm McLean kirjutas:
> On Sunday, 3 April 2022 at 20:20:36 UTC+1, David Brown wrote:
>> On 03/04/2022 20:30, Malcolm McLean wrote:
>>> On Sunday, 3 April 2022 at 15:02:19 UTC+1, Öö Tiib wrote:
>>>> On Sunday, 3 April 2022 at 14:47:06 UTC+3, Malcolm McLean wrote:
>>>>> On Sunday, 3 April 2022 at 12:03:08 UTC+1, David Brown wrote:
>>>>>> On 02/04/2022 17:39, Mut...@dastardlyhq.com wrote:
>>>>>>> On Sat, 2 Apr 2022 17:27:39 +0200
>>>>>>> David Brown <david...@hesbynett.no> wrote:
>>>>>>>> On 02/04/2022 16:28, Mut...@dastardlyhq.com wrote:
>>>>>>>>> On Sat, 2 Apr 2022 14:12:17 +0200
>>>>>>>>> David Brown <david...@hesbynett.no> wrote:
>>>>>>>>>> It seems gcc has handled this as:
>>>>>>>>>>
>>>>>>>>>> ++i;
>>>>>>>>>> ++i;
>>>>>>>>>> a = i;
>>>>>>>>>> b = i;
>>>>>>>>>>
>>>>>>>>>> and AFAIUI, this interleaving is not allowed in C++17.
>>>>>>>>>>
>>>>>>>>>> Prior to C++17, the code could do anything - segfault, return 42, buy
>>>>>>>>>> you flowers - whatever it liked.
>>>>>>>>>
>>>>>>>>> Why would it segfault? Its simply incrementing values albeit in an
>>>>>>>>> indeterminate order.
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> In C++17, the incrementing is indeterminate order. Prior to that, it is
>>>>>>>> undefined behaviour. UB /could/ do anything. If the compiler happens
>>>>>>>
>>>>>>> Undefined simply means no one cared enough to define it. The compiler writers
>>>>>>> would have to deliberately change their parameter parsing and stack pushing
>>>>>>> code in order to crash in this instance.
>>>>>>>
>>>>>> That kind of argument works when code can be taken alone in small
>>>>>> snippets, without context. But real code is rarely alone. Once things
>>>>>> are going wrong, problems can multiply.
>>>>>>
>>>>>> Typically, undefined behaviour means the compiler can take short-cuts.
>>>>>> That might mean "doing the obvious thing", but it might mean getting
>>>>>> strange and inconsistent behaviour. Given "a = b + c;" using signed int
>>>>>> types, the compiler is likely to generate the assembly code for a two's
>>>>>> complement wrapping addition on most processors. But if it knows that
>>>>>> "b" and "c" are non-negative, then it also knows that "a" is
>>>>>> non-negative and can use that for optimisation - even if the addition
>>>>>> overflowed and "a" contains a negative number.
>>>>>>>> POSIX, documented compiler features, etc.), then you can't rely on it
>>>>>>>> for any purpose.
>>>>>>>
>>>>>>> You can't rely on a rusty bicycle working, but its not going to shoot you in
>>>>>>> the head.
>>>>>>>
>>>>>> The bike won't shoot you - but it could fall apart when you are cycling
>>>>>> down a road, and cars swerving to miss you cause a pile-up with dozens
>>>>>> killed. Undefined behaviour has no inherent limits to its consequences
>>>>>> - that's why you should work to avoid it.
>>>>>>
>>>>>> (And no, despite some people's misunderstandings, this is not due to
>>>>>> overly-enthusiastic optimising compilers or flaws in the language - it
>>>>>> is fundamental to all programming, and fundamental to any kind of error
>>>>>> or mistake in the code. Different compilers, languages, and programming
>>>>>> styles can influence how the risks build up, but not the principles.)
>>>>>>
>>>>> The central issue is that, for some programs, the worst thing you can do is
>>>>> terminate. For example a video game. If it crashes the game is ruined.
>>>> While the program is still in development process and so in hands of
>>>> developers and testers then cheapest to track down defect is when program
>>>> refuses to compile and next best is runtime crash. It does not matter if it is
>>>> for entertainment or for something more serious, what matters is
>>>> development cost.
>>>>
>>> If you're writing control systems for nuclear reactors, you have to have really
>>> tight quality control, including proving of algorithms. But if you're doing
>>> everyday programming, you just don't have those resources.
>>>
>>>
>> You may not have the resources - or the ability - to write bug-free
>> code. That does not mean you should consider some kinds of bugs
>> "acceptable". And it certainly does not mean that you should consider
>> some classes of undefined behaviour as "nothing to worry about, really -
>> there's no need to be careful about integer arithmetic because there's a
>> good chance no one will complain about the mistake".
>>
>> I can appreciate if you find an integer overflow bug and you mark it as
>> low priority in your long list of bugs in the program because it just
>> causes a visual glitch.
>>
>> I cannot accept the attitude that you are happy to write knowingly
>> incorrect code and hope it causes nothing more than a visual glitch.
>>
>> Ultimately, these two attitudes can lead to the same thing - programs
>> released even though you know there are bugs in them, because you don't
>> have the time or resources to fix everything. Real life is not perfect.
>> But there is a very big difference in the philosophies here.
>>
> You fail to follow.
> Say we have this code.
> 
> FILE *fp = openfile();
> int width = readinteger(fp);
> int height = readinteger(fp);

Hoping both openfile() and readinteger() functions check for errors 
internally and throw relevant exceptions.

> int Npixels = width * height;  // potential bug here
> 
> Now of course we should put in a test before multiplying two integers
> from an outside source. But these sorts of errors happen. The question is
> that, given that despite all our best efforts this code has got through to
> production, how do we want the program to behave?

If a bug has slipped through into production, we want to minimize the 
cost of dealing with the bug. These costs will depend on a myriad of 
factors, like how likely the program would still function correctly even 
if the bug is hit, how many customers are affected, how costly is the QA 
cycle for releasing a patch version, how costly is losing some customers 
because of the bug, etc. There is no single answer. For the customer it 
does not really matter if they cannot use our program because we had put 
too many assertions/aborts in it, or because there are show-stopper bugs 
in it.

> Should we compile with the option "abort on arithmetic overflow" or
> "wrap on arithmetic overflow"?.

That will also depend on other considerations, like how much performance 
is lost for detecting the arithmetic overflow, and how devastating it 
would be to have an incorrect result instead of a program abort, or vice 
versa.

> 
> As an exercise to the reader, there's a school of thought that these values
> should be size_t. What are the consequences of that policy for program
> robustness?

Widths, heights, and lengths are not periodic variables like e.g. 
angles, so it would be counter-productive to try to encode them via 
periodic types like unsigned integrals in C++. For starters, the 
overflows would become defined behavior with unsigned types, meaning 
that one cannot trap them, or even tell apart bugs and features.

So here, clearly a signed integer type should be preferred. The exact 
preferred signed integer type for scalar variables should match the 
hardware word, nowadays this is int64.


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


#83444 — Re: GCC hasn't even gotten around to sequencing argument evaluation

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2022-04-03 15:40 -0700
SubjectRe: GCC hasn't even gotten around to sequencing argument evaluation
Message-ID<3d7bfd9f-c003-46eb-a82a-cd66ba483eaan@googlegroups.com>
In reply to#83443
On Sunday, 3 April 2022 at 22:40:57 UTC+1, Paavo Helde wrote:
> 03.04.2022 22:49 Malcolm McLean kirjutas: 
> > On Sunday, 3 April 2022 at 20:20:36 UTC+1, David Brown wrote: 
> >> On 03/04/2022 20:30, Malcolm McLean wrote: 
> >>> On Sunday, 3 April 2022 at 15:02:19 UTC+1, Öö Tiib wrote: 
> >>>> On Sunday, 3 April 2022 at 14:47:06 UTC+3, Malcolm McLean wrote: 
> >>>>> On Sunday, 3 April 2022 at 12:03:08 UTC+1, David Brown wrote: 
> >>>>>> On 02/04/2022 17:39, Mut...@dastardlyhq.com wrote: 
> >>>>>>> On Sat, 2 Apr 2022 17:27:39 +0200 
> >>>>>>> David Brown <david...@hesbynett.no> wrote: 
> >>>>>>>> On 02/04/2022 16:28, Mut...@dastardlyhq.com wrote: 
> >>>>>>>>> On Sat, 2 Apr 2022 14:12:17 +0200 
> >>>>>>>>> David Brown <david...@hesbynett.no> wrote: 
> >>>>>>>>>> It seems gcc has handled this as: 
> >>>>>>>>>> 
> >>>>>>>>>> ++i; 
> >>>>>>>>>> ++i; 
> >>>>>>>>>> a = i; 
> >>>>>>>>>> b = i; 
> >>>>>>>>>> 
> >>>>>>>>>> and AFAIUI, this interleaving is not allowed in C++17. 
> >>>>>>>>>> 
> >>>>>>>>>> Prior to C++17, the code could do anything - segfault, return 42, buy 
> >>>>>>>>>> you flowers - whatever it liked. 
> >>>>>>>>> 
> >>>>>>>>> Why would it segfault? Its simply incrementing values albeit in an 
> >>>>>>>>> indeterminate order. 
> >>>>>>>>> 
> >>>>>>>> 
> >>>>>>>> 
> >>>>>>>> In C++17, the incrementing is indeterminate order. Prior to that, it is 
> >>>>>>>> undefined behaviour. UB /could/ do anything. If the compiler happens 
> >>>>>>> 
> >>>>>>> Undefined simply means no one cared enough to define it. The compiler writers 
> >>>>>>> would have to deliberately change their parameter parsing and stack pushing 
> >>>>>>> code in order to crash in this instance. 
> >>>>>>> 
> >>>>>> That kind of argument works when code can be taken alone in small 
> >>>>>> snippets, without context. But real code is rarely alone. Once things 
> >>>>>> are going wrong, problems can multiply. 
> >>>>>> 
> >>>>>> Typically, undefined behaviour means the compiler can take short-cuts. 
> >>>>>> That might mean "doing the obvious thing", but it might mean getting 
> >>>>>> strange and inconsistent behaviour. Given "a = b + c;" using signed int 
> >>>>>> types, the compiler is likely to generate the assembly code for a two's 
> >>>>>> complement wrapping addition on most processors. But if it knows that 
> >>>>>> "b" and "c" are non-negative, then it also knows that "a" is 
> >>>>>> non-negative and can use that for optimisation - even if the addition 
> >>>>>> overflowed and "a" contains a negative number. 
> >>>>>>>> POSIX, documented compiler features, etc.), then you can't rely on it 
> >>>>>>>> for any purpose. 
> >>>>>>> 
> >>>>>>> You can't rely on a rusty bicycle working, but its not going to shoot you in 
> >>>>>>> the head. 
> >>>>>>> 
> >>>>>> The bike won't shoot you - but it could fall apart when you are cycling 
> >>>>>> down a road, and cars swerving to miss you cause a pile-up with dozens 
> >>>>>> killed. Undefined behaviour has no inherent limits to its consequences 
> >>>>>> - that's why you should work to avoid it. 
> >>>>>> 
> >>>>>> (And no, despite some people's misunderstandings, this is not due to 
> >>>>>> overly-enthusiastic optimising compilers or flaws in the language - it 
> >>>>>> is fundamental to all programming, and fundamental to any kind of error 
> >>>>>> or mistake in the code. Different compilers, languages, and programming 
> >>>>>> styles can influence how the risks build up, but not the principles.) 
> >>>>>> 
> >>>>> The central issue is that, for some programs, the worst thing you can do is 
> >>>>> terminate. For example a video game. If it crashes the game is ruined. 
> >>>> While the program is still in development process and so in hands of 
> >>>> developers and testers then cheapest to track down defect is when program 
> >>>> refuses to compile and next best is runtime crash. It does not matter if it is 
> >>>> for entertainment or for something more serious, what matters is 
> >>>> development cost. 
> >>>> 
> >>> If you're writing control systems for nuclear reactors, you have to have really 
> >>> tight quality control, including proving of algorithms. But if you're doing 
> >>> everyday programming, you just don't have those resources. 
> >>> 
> >>> 
> >> You may not have the resources - or the ability - to write bug-free 
> >> code. That does not mean you should consider some kinds of bugs 
> >> "acceptable". And it certainly does not mean that you should consider 
> >> some classes of undefined behaviour as "nothing to worry about, really - 
> >> there's no need to be careful about integer arithmetic because there's a 
> >> good chance no one will complain about the mistake". 
> >> 
> >> I can appreciate if you find an integer overflow bug and you mark it as 
> >> low priority in your long list of bugs in the program because it just 
> >> causes a visual glitch. 
> >> 
> >> I cannot accept the attitude that you are happy to write knowingly 
> >> incorrect code and hope it causes nothing more than a visual glitch. 
> >> 
> >> Ultimately, these two attitudes can lead to the same thing - programs 
> >> released even though you know there are bugs in them, because you don't 
> >> have the time or resources to fix everything. Real life is not perfect. 
> >> But there is a very big difference in the philosophies here. 
> >> 
> > You fail to follow. 
> > Say we have this code. 
> > 
> > FILE *fp = openfile(); 
> > int width = readinteger(fp); 
> > int height = readinteger(fp);
> Hoping both openfile() and readinteger() functions check for errors 
> internally and throw relevant exceptions.
> > int Npixels = width * height; // potential bug here 
> > 
> > Now of course we should put in a test before multiplying two integers 
> > from an outside source. But these sorts of errors happen. The question is 
> > that, given that despite all our best efforts this code has got through to 
> > production, how do we want the program to behave?
> If a bug has slipped through into production, we want to minimize the 
> cost of dealing with the bug. These costs will depend on a myriad of 
> factors, like how likely the program would still function correctly even 
> if the bug is hit, how many customers are affected, how costly is the QA 
> cycle for releasing a patch version, how costly is losing some customers 
> because of the bug, etc. There is no single answer. For the customer it 
> does not really matter if they cannot use our program because we had put 
> too many assertions/aborts in it, or because there are show-stopper bugs 
> in it.
>
That can be a consideration. Not the immediate cost of the bug to the user, 
but the cost of dealing with the bug reports. Unless the software really is critical,
so that any error whatsoever requires immediate discontinuation of the
software, a bug that ships is unlikely to make the software unusable. Testers
are rarely that incompetent. In this case, what would happen is that an
integer overflow would occur when fed a malformed file with huge
dimensions. The user could still use the software as long as he only loaded
well-formed files. 

As you say, there can be no single answer. In general, however, it's better to
terminate with an error message. That's no different to the computer losing
power. Producing wrong results, on the other hand, can have far-reaching
consequences. But there are exceptions, like video games.

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


#83448 — Re: GCC hasn't even gotten around to sequencing argument evaluation

FromDavid Brown <david.brown@hesbynett.no>
Date2022-04-04 09:13 +0200
SubjectRe: GCC hasn't even gotten around to sequencing argument evaluation
Message-ID<t2e5qm$dde$1@dont-email.me>
In reply to#83444
On 04/04/2022 00:40, Malcolm McLean wrote:

> As you say, there can be no single answer.

True.

> In general, however, it's better to
> terminate with an error message.

Wrong.  There is no "in general".

> That's no different to the computer losing
> power.

Wrong.

> Producing wrong results, on the other hand, can have far-reaching
> consequences.

Correct.

> But there are exceptions, like video games.

Wrong.

Incorrect results in video games can most certainly have far-reaching 
consequences.  Use your imagination a bit.


In some types of code, it is possible to track, contain or limit certain 
types of errors, accept that these can occur, and control the 
consequences.  This is especially true of run-time errors (like failure 
to access a file), rather than software bugs.  But it can even apply to 
software bugs too - typically using managed virtual machines or other 
constrained environments to run the code.

There is also some code for which particular types of wrong answer are 
not a big problem.  It depends on what you are doing with the results, 
and what happens afterwards.  If you have a function that does some 
calculations and prints the results which is then interpreted by a 
human, it is not unlikely that an incorrect result will be 
inconsequential.  Overflows in the calculation might then not be serious 
a problem.  But if those results are used for other purposes, they most 
certainly could be.

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


#83447 — Re: GCC hasn't even gotten around to sequencing argument evaluation

FromDavid Brown <david.brown@hesbynett.no>
Date2022-04-04 09:02 +0200
SubjectRe: GCC hasn't even gotten around to sequencing argument evaluation
Message-ID<t2e55d$920$1@dont-email.me>
In reply to#83442
On 03/04/2022 21:49, Malcolm McLean wrote:
> On Sunday, 3 April 2022 at 20:20:36 UTC+1, David Brown wrote:
>> On 03/04/2022 20:30, Malcolm McLean wrote:
>>> On Sunday, 3 April 2022 at 15:02:19 UTC+1, Öö Tiib wrote:
>>>> On Sunday, 3 April 2022 at 14:47:06 UTC+3, Malcolm McLean wrote:
>>>>> On Sunday, 3 April 2022 at 12:03:08 UTC+1, David Brown wrote:
>>>>>> On 02/04/2022 17:39, Mut...@dastardlyhq.com wrote:
>>>>>>> On Sat, 2 Apr 2022 17:27:39 +0200
>>>>>>> David Brown <david...@hesbynett.no> wrote:
>>>>>>>> On 02/04/2022 16:28, Mut...@dastardlyhq.com wrote:
>>>>>>>>> On Sat, 2 Apr 2022 14:12:17 +0200
>>>>>>>>> David Brown <david...@hesbynett.no> wrote:
>>>>>>>>>> It seems gcc has handled this as:
>>>>>>>>>>
>>>>>>>>>> ++i;
>>>>>>>>>> ++i;
>>>>>>>>>> a = i;
>>>>>>>>>> b = i;
>>>>>>>>>>
>>>>>>>>>> and AFAIUI, this interleaving is not allowed in C++17.
>>>>>>>>>>
>>>>>>>>>> Prior to C++17, the code could do anything - segfault, return 42, buy
>>>>>>>>>> you flowers - whatever it liked.
>>>>>>>>>
>>>>>>>>> Why would it segfault? Its simply incrementing values albeit in an
>>>>>>>>> indeterminate order.
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> In C++17, the incrementing is indeterminate order. Prior to that, it is
>>>>>>>> undefined behaviour. UB /could/ do anything. If the compiler happens
>>>>>>>
>>>>>>> Undefined simply means no one cared enough to define it. The compiler writers
>>>>>>> would have to deliberately change their parameter parsing and stack pushing
>>>>>>> code in order to crash in this instance.
>>>>>>>
>>>>>> That kind of argument works when code can be taken alone in small
>>>>>> snippets, without context. But real code is rarely alone. Once things
>>>>>> are going wrong, problems can multiply.
>>>>>>
>>>>>> Typically, undefined behaviour means the compiler can take short-cuts.
>>>>>> That might mean "doing the obvious thing", but it might mean getting
>>>>>> strange and inconsistent behaviour. Given "a = b + c;" using signed int
>>>>>> types, the compiler is likely to generate the assembly code for a two's
>>>>>> complement wrapping addition on most processors. But if it knows that
>>>>>> "b" and "c" are non-negative, then it also knows that "a" is
>>>>>> non-negative and can use that for optimisation - even if the addition
>>>>>> overflowed and "a" contains a negative number.
>>>>>>>> POSIX, documented compiler features, etc.), then you can't rely on it
>>>>>>>> for any purpose.
>>>>>>>
>>>>>>> You can't rely on a rusty bicycle working, but its not going to shoot you in
>>>>>>> the head.
>>>>>>>
>>>>>> The bike won't shoot you - but it could fall apart when you are cycling
>>>>>> down a road, and cars swerving to miss you cause a pile-up with dozens
>>>>>> killed. Undefined behaviour has no inherent limits to its consequences
>>>>>> - that's why you should work to avoid it.
>>>>>>
>>>>>> (And no, despite some people's misunderstandings, this is not due to
>>>>>> overly-enthusiastic optimising compilers or flaws in the language - it
>>>>>> is fundamental to all programming, and fundamental to any kind of error
>>>>>> or mistake in the code. Different compilers, languages, and programming
>>>>>> styles can influence how the risks build up, but not the principles.)
>>>>>>
>>>>> The central issue is that, for some programs, the worst thing you can do is
>>>>> terminate. For example a video game. If it crashes the game is ruined.
>>>> While the program is still in development process and so in hands of
>>>> developers and testers then cheapest to track down defect is when program
>>>> refuses to compile and next best is runtime crash. It does not matter if it is
>>>> for entertainment or for something more serious, what matters is
>>>> development cost.
>>>>
>>> If you're writing control systems for nuclear reactors, you have to have really
>>> tight quality control, including proving of algorithms. But if you're doing
>>> everyday programming, you just don't have those resources.
>>>
>>>
>> You may not have the resources - or the ability - to write bug-free
>> code. That does not mean you should consider some kinds of bugs
>> "acceptable". And it certainly does not mean that you should consider
>> some classes of undefined behaviour as "nothing to worry about, really -
>> there's no need to be careful about integer arithmetic because there's a
>> good chance no one will complain about the mistake".
>>
>> I can appreciate if you find an integer overflow bug and you mark it as
>> low priority in your long list of bugs in the program because it just
>> causes a visual glitch.
>>
>> I cannot accept the attitude that you are happy to write knowingly
>> incorrect code and hope it causes nothing more than a visual glitch.
>>
>> Ultimately, these two attitudes can lead to the same thing - programs
>> released even though you know there are bugs in them, because you don't
>> have the time or resources to fix everything. Real life is not perfect.
>> But there is a very big difference in the philosophies here.
>>
> You fail to follow.
> Say we have this code.
> 
> FILE *fp = openfile();
> int width = readinteger(fp);
> int height = readinteger(fp);
> int Npixels = width * height;  // potential bug here
> 
> Now of course we should put in a test before multiplying two integers
> from an outside source. But these sorts of errors happen. The question is
> that, given that despite all our best efforts this code has got through to
> production, how do we want the program to behave?
> 
> Should we compile with the option "abort on arithmetic overflow" or
> "wrap on arithmetic overflow"?.

Obviously you don't want "wrap on arithmetic overflow", because a 
negative size would be absurd and could lead to all sorts of problems. 
And in a game you probably don't want to enable a compiler feature that 
can produce slower code.  (Few compilers even support "wrap on overflow" 
- gcc and clang with "-fwrapv" are the only ones I know.)

During development and testing, you might want "abort on arithmetic 
overflow" to find the flaws.

Beyond that, it depends on whether the file in question is considered 
part of the program or not.  If it is part of the program, you can trust 
it - and thus you want "undefined behaviour on overflow" or you'd really 
have to check /everything/ in the file.  If it is not part of the 
program, it is outside information and must be sanitized before use. 
And then "undefined behaviour on overflow" is fine.

> 
> As an exercise to the reader, there's a school of thought that these values
> should be size_t. What are the consequences of that policy for program
> robustness?

It is just as bad.

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


#83453 — Re: GCC hasn't even gotten around to sequencing argument evaluation

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2022-04-04 02:07 -0700
SubjectRe: GCC hasn't even gotten around to sequencing argument evaluation
Message-ID<567bd57a-021d-469b-a12b-d4c1371b97d3n@googlegroups.com>
In reply to#83447
On Monday, 4 April 2022 at 08:02:21 UTC+1, David Brown wrote:
> On 03/04/2022 21:49, Malcolm McLean wrote: 
> > On Sunday, 3 April 2022 at 20:20:36 UTC+1, David Brown wrote: 
> >> On 03/04/2022 20:30, Malcolm McLean wrote: 
> >>> On Sunday, 3 April 2022 at 15:02:19 UTC+1, Öö Tiib wrote: 
> >>>> On Sunday, 3 April 2022 at 14:47:06 UTC+3, Malcolm McLean wrote: 
> >>>>> On Sunday, 3 April 2022 at 12:03:08 UTC+1, David Brown wrote: 
> >>>>>> On 02/04/2022 17:39, Mut...@dastardlyhq.com wrote: 
> >>>>>>> On Sat, 2 Apr 2022 17:27:39 +0200 
> >>>>>>> David Brown <david...@hesbynett.no> wrote: 
> >>>>>>>> On 02/04/2022 16:28, Mut...@dastardlyhq.com wrote: 
> >>>>>>>>> On Sat, 2 Apr 2022 14:12:17 +0200 
> >>>>>>>>> David Brown <david...@hesbynett.no> wrote: 
> >>>>>>>>>> It seems gcc has handled this as: 
> >>>>>>>>>> 
> >>>>>>>>>> ++i; 
> >>>>>>>>>> ++i; 
> >>>>>>>>>> a = i; 
> >>>>>>>>>> b = i; 
> >>>>>>>>>> 
> >>>>>>>>>> and AFAIUI, this interleaving is not allowed in C++17. 
> >>>>>>>>>> 
> >>>>>>>>>> Prior to C++17, the code could do anything - segfault, return 42, buy 
> >>>>>>>>>> you flowers - whatever it liked. 
> >>>>>>>>> 
> >>>>>>>>> Why would it segfault? Its simply incrementing values albeit in an 
> >>>>>>>>> indeterminate order. 
> >>>>>>>>> 
> >>>>>>>> 
> >>>>>>>> 
> >>>>>>>> In C++17, the incrementing is indeterminate order. Prior to that, it is 
> >>>>>>>> undefined behaviour. UB /could/ do anything. If the compiler happens 
> >>>>>>> 
> >>>>>>> Undefined simply means no one cared enough to define it. The compiler writers 
> >>>>>>> would have to deliberately change their parameter parsing and stack pushing 
> >>>>>>> code in order to crash in this instance. 
> >>>>>>> 
> >>>>>> That kind of argument works when code can be taken alone in small 
> >>>>>> snippets, without context. But real code is rarely alone. Once things 
> >>>>>> are going wrong, problems can multiply. 
> >>>>>> 
> >>>>>> Typically, undefined behaviour means the compiler can take short-cuts. 
> >>>>>> That might mean "doing the obvious thing", but it might mean getting 
> >>>>>> strange and inconsistent behaviour. Given "a = b + c;" using signed int 
> >>>>>> types, the compiler is likely to generate the assembly code for a two's 
> >>>>>> complement wrapping addition on most processors. But if it knows that 
> >>>>>> "b" and "c" are non-negative, then it also knows that "a" is 
> >>>>>> non-negative and can use that for optimisation - even if the addition 
> >>>>>> overflowed and "a" contains a negative number. 
> >>>>>>>> POSIX, documented compiler features, etc.), then you can't rely on it 
> >>>>>>>> for any purpose. 
> >>>>>>> 
> >>>>>>> You can't rely on a rusty bicycle working, but its not going to shoot you in 
> >>>>>>> the head. 
> >>>>>>> 
> >>>>>> The bike won't shoot you - but it could fall apart when you are cycling 
> >>>>>> down a road, and cars swerving to miss you cause a pile-up with dozens 
> >>>>>> killed. Undefined behaviour has no inherent limits to its consequences 
> >>>>>> - that's why you should work to avoid it. 
> >>>>>> 
> >>>>>> (And no, despite some people's misunderstandings, this is not due to 
> >>>>>> overly-enthusiastic optimising compilers or flaws in the language - it 
> >>>>>> is fundamental to all programming, and fundamental to any kind of error 
> >>>>>> or mistake in the code. Different compilers, languages, and programming 
> >>>>>> styles can influence how the risks build up, but not the principles.) 
> >>>>>> 
> >>>>> The central issue is that, for some programs, the worst thing you can do is 
> >>>>> terminate. For example a video game. If it crashes the game is ruined. 
> >>>> While the program is still in development process and so in hands of 
> >>>> developers and testers then cheapest to track down defect is when program 
> >>>> refuses to compile and next best is runtime crash. It does not matter if it is 
> >>>> for entertainment or for something more serious, what matters is 
> >>>> development cost. 
> >>>> 
> >>> If you're writing control systems for nuclear reactors, you have to have really 
> >>> tight quality control, including proving of algorithms. But if you're doing 
> >>> everyday programming, you just don't have those resources. 
> >>> 
> >>> 
> >> You may not have the resources - or the ability - to write bug-free 
> >> code. That does not mean you should consider some kinds of bugs 
> >> "acceptable". And it certainly does not mean that you should consider 
> >> some classes of undefined behaviour as "nothing to worry about, really - 
> >> there's no need to be careful about integer arithmetic because there's a 
> >> good chance no one will complain about the mistake". 
> >> 
> >> I can appreciate if you find an integer overflow bug and you mark it as 
> >> low priority in your long list of bugs in the program because it just 
> >> causes a visual glitch. 
> >> 
> >> I cannot accept the attitude that you are happy to write knowingly 
> >> incorrect code and hope it causes nothing more than a visual glitch. 
> >> 
> >> Ultimately, these two attitudes can lead to the same thing - programs 
> >> released even though you know there are bugs in them, because you don't 
> >> have the time or resources to fix everything. Real life is not perfect. 
> >> But there is a very big difference in the philosophies here. 
> >> 
> > You fail to follow. 
> > Say we have this code. 
> > 
> > FILE *fp = openfile(); 
> > int width = readinteger(fp); 
> > int height = readinteger(fp); 
> > int Npixels = width * height; // potential bug here 
> > 
> > Now of course we should put in a test before multiplying two integers 
> > from an outside source. But these sorts of errors happen. The question is 
> > that, given that despite all our best efforts this code has got through to 
> > production, how do we want the program to behave? 
> > 
> > Should we compile with the option "abort on arithmetic overflow" or 
> > "wrap on arithmetic overflow"?.
> Obviously you don't want "wrap on arithmetic overflow", because a 
> negative size would be absurd and could lead to all sorts of problems. 
> And in a game you probably don't want to enable a compiler feature that 
> can produce slower code. (Few compilers even support "wrap on overflow" 
> - gcc and clang with "-fwrapv" are the only ones I know.) 
>
Generally the processors primitive operations will wrap two's complement
arithmetic. So to raise a signal on overflow is more expensive rather
than less expensive.
>
> During development and testing, you might want "abort on arithmetic 
> overflow" to find the flaws. It's hard to think of  situation where you want wrapping during debug.
Release is a different matter.
> 
> Beyond that, it depends on whether the file in question is considered 
> part of the program or not. If it is part of the program, you can trust 
> it - and thus you want "undefined behaviour on overflow" or you'd really 
> have to check /everything/ in the file. If it is not part of the 
> program, it is outside information and must be sanitized before use. 
> And then "undefined behaviour on overflow" is fine.
> 
Before we can write x = a * b, with signed integer types, we need to know
that the product will fit in x. That's very burdensome, and most of the time 
we know that a and b must be small. If a and b are read in from a user-supplied
file, the we don't know that, of course.
> 
> > As an exercise to the reader, there's a school of thought that these values 
> > should be size_t. What are the consequences of that policy for program 
> > robustness?
> It is just as bad.
>
It's impossible to tell the program to raise the signal on overflow, because
in this case overflow is defined by the standard. it's not the case that
defined behaviour is automatically better than undefined behaviour.
Often an undefined behaviour bug can be easier to mitigate (the program 
crashes on load of a corrupt file with the message "integer overflow"
rather than opening up a security bug that allows a specially-crafted
exploit image to execute arbitrary machine code).

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


#83458 — Re: GCC hasn't even gotten around to sequencing argument evaluation

FromDavid Brown <david.brown@hesbynett.no>
Date2022-04-04 13:28 +0200
SubjectRe: GCC hasn't even gotten around to sequencing argument evaluation
Message-ID<t2ekpd$qpk$1@dont-email.me>
In reply to#83453
On 04/04/2022 11:07, Malcolm McLean wrote:
> On Monday, 4 April 2022 at 08:02:21 UTC+1, David Brown wrote:
>> On 03/04/2022 21:49, Malcolm McLean wrote:
>>> On Sunday, 3 April 2022 at 20:20:36 UTC+1, David Brown wrote:
>>>> On 03/04/2022 20:30, Malcolm McLean wrote:
<snip>
>>>>> If you're writing control systems for nuclear reactors, you have to have really
>>>>> tight quality control, including proving of algorithms. But if you're doing
>>>>> everyday programming, you just don't have those resources.
>>>>>
>>>>>
>>>> You may not have the resources - or the ability - to write bug-free
>>>> code. That does not mean you should consider some kinds of bugs
>>>> "acceptable". And it certainly does not mean that you should consider
>>>> some classes of undefined behaviour as "nothing to worry about, really -
>>>> there's no need to be careful about integer arithmetic because there's a
>>>> good chance no one will complain about the mistake".
>>>>
>>>> I can appreciate if you find an integer overflow bug and you mark it as
>>>> low priority in your long list of bugs in the program because it just
>>>> causes a visual glitch.
>>>>
>>>> I cannot accept the attitude that you are happy to write knowingly
>>>> incorrect code and hope it causes nothing more than a visual glitch.
>>>>
>>>> Ultimately, these two attitudes can lead to the same thing - programs
>>>> released even though you know there are bugs in them, because you don't
>>>> have the time or resources to fix everything. Real life is not perfect.
>>>> But there is a very big difference in the philosophies here.
>>>>
>>> You fail to follow.
>>> Say we have this code.
>>>
>>> FILE *fp = openfile();
>>> int width = readinteger(fp);
>>> int height = readinteger(fp);
>>> int Npixels = width * height; // potential bug here
>>>
>>> Now of course we should put in a test before multiplying two integers
>>> from an outside source. But these sorts of errors happen. The question is
>>> that, given that despite all our best efforts this code has got through to
>>> production, how do we want the program to behave?
>>>
>>> Should we compile with the option "abort on arithmetic overflow" or
>>> "wrap on arithmetic overflow"?.
>> Obviously you don't want "wrap on arithmetic overflow", because a
>> negative size would be absurd and could lead to all sorts of problems.
>> And in a game you probably don't want to enable a compiler feature that
>> can produce slower code. (Few compilers even support "wrap on overflow"
>> - gcc and clang with "-fwrapv" are the only ones I know.)
>>
> Generally the processors primitive operations will wrap two's complement
> arithmetic. So to raise a signal on overflow is more expensive rather
> than less expensive.

"Generally" means "not always".  For the very simple case of adding two 
numbers, wrapping is typically as efficient as UB on overflow. 
(Remember that wrapping is a perfectly acceptable "implementation" of 
UB.)  Once you start including comparisons, or mixing types of different 
sizes, it is not always as simple.

>>
>> During development and testing, you might want "abort on arithmetic
>> overflow" to find the flaws. It's hard to think of  situation where you want wrapping during debug.
> Release is a different matter.
>>
>> Beyond that, it depends on whether the file in question is considered
>> part of the program or not. If it is part of the program, you can trust
>> it - and thus you want "undefined behaviour on overflow" or you'd really
>> have to check /everything/ in the file. If it is not part of the
>> program, it is outside information and must be sanitized before use.
>> And then "undefined behaviour on overflow" is fine.
>>
> Before we can write x = a * b, with signed integer types, we need to know
> that the product will fit in x. 

You also need that for unsigned types, if you are looking for a result 
that matches normal multiplication rather than modulo operations.  (Just 
because arithmetic is fully defined for unsigned types, does not mean 
your results are always correct.)

> That's very burdensome, and most of the time
> we know that a and b must be small. If a and b are read in from a user-supplied
> file, the we don't know that, of course.

Then don't multiply them until you /do/ know.

Or make sure the user is aware that this is all "garbage in, garbage 
out" and it is their responsibility to provide valid data in the files 
and that your program makes no guarantees of correct or safe behaviour 
given invalid data.

>>
>>> As an exercise to the reader, there's a school of thought that these values
>>> should be size_t. What are the consequences of that policy for program
>>> robustness?
>> It is just as bad.
>>
> It's impossible to tell the program to raise the signal on overflow, because
> in this case overflow is defined by the standard. 

I mean using size_t as an arithmetic type, without care or consideration 
for the values, is just as bad as using "int".  The fact that the 
arithmetic is defined behaviour does not guarantee you correct results 
(depending on what you view as "correct").  In terms of getting the 
mathematically (assuming you don't actually want modulo wrapping) 
correct results from calculations, unsigned types are just as bad as 
signed types.

> it's not the case that
> defined behaviour is automatically better than undefined behaviour.
> Often an undefined behaviour bug can be easier to mitigate (the program
> crashes on load of a corrupt file with the message "integer overflow"
> rather than opening up a security bug that allows a specially-crafted
> exploit image to execute arbitrary machine code).

Bugs are bugs.  Once you have executed buggy code, all bets are off. 
There are no inherent limitations to the results - no guarantees that 
the effects will be minor "glitches", no guarantees that it will not be 
a security problem, and no guarantees that you'll get a crash or error 
message.

It can be good to write code in a way that allows certain classes of 
bugs to be turned into defined behaviour that guarantees an error 
message - "sanitizers" are useful development tools.  But it is even 
better if you can find development processes that reduce the risk of 
bugs being written into the code, or increase their likelihood of being 
spotted early in the process.

Start by eliminating the idea that you can be lazy about some mistakes 
because they just cause visual glitches.  Leave "advanced" stuff like 
choice of integer types until you have first understood the importance 
of writing correct code.

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


#83461 — Re: GCC hasn't even gotten around to sequencing argument evaluation

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2022-04-04 06:01 -0700
SubjectRe: GCC hasn't even gotten around to sequencing argument evaluation
Message-ID<36efdae0-f340-4958-b082-bd4932e87e15n@googlegroups.com>
In reply to#83458
On Monday, 4 April 2022 at 12:29:00 UTC+1, David Brown wrote:
> On 04/04/2022 11:07, Malcolm McLean wrote: 
> 
> > Generally the processors primitive operations will wrap two's complement 
> > arithmetic. So to raise a signal on overflow is more expensive rather 
> > than less expensive.
> "Generally" means "not always". For the very simple case of adding two 
> numbers, wrapping is typically as efficient as UB on overflow. 
> (Remember that wrapping is a perfectly acceptable "implementation" of 
> UB.) Once you start including comparisons, or mixing types of different 
> sizes, it is not always as simple.
>
If you wrap, you do not raise a signal. Generally this is cheaper than raising
a signal because wrapping requires less circuitry than detecting overflow
and raising  a signal. You've got it the wrong way round. Now if I was 
arrongant and patronising like you, I'd say something arrrogant and
patronising at this point.  
> 
> > Before we can write x = a * b, with signed integer types, we need to know 
> > that the product will fit in x.
> You also need that for unsigned types, if you are looking for a result 
> that matches normal multiplication rather than modulo operations. (Just 
> because arithmetic is fully defined for unsigned types, does not mean 
> your results are always correct.)

You're repeating my points back to me, without realising that you are doing so.
I've alreeady made the point that unsigned overflow is often worse. Because
it is defined behaviour. You cannot get an exception.
> > That's very burdensome, and most of the time 
> > we know that a and b must be small. If a and b are read in from a user-supplied 
> > file, the we don't know that, of course.
> Then don't multiply them until you /do/ know. 
> 
> Or make sure the user is aware that this is all "garbage in, garbage 
> out" and it is their responsibility to provide valid data in the files 
> and that your program makes no guarantees of correct or safe behaviour 
> given invalid data.
>
That's a possibility. In fact you normally say that the software offers no
guarantees of correct or safe behaviour undeer any circumstances.
Liability is limited to the amount of money the customer paid for the
software. You have no commeercial experience, obviously.
> 
> It can be good to write code in a way that allows certain classes of 
> bugs to be turned into defined behaviour that guarantees an error 
> message - "sanitizers" are useful development tools. But it is even 
> better if you can find development processes that reduce the risk of 
> bugs being written into the code, or increase their likelihood of being 
> spotted early in the process. 
>
And it can be good to turn the undefined behaviour (by C++) of 
integer overflow into the defined behaviour (by the compiler) of
raising an exception. Then bugs are less likely to be serious. You
show no ability to understand  this point.
>
> Start by eliminating the idea that you can be lazy about some mistakes 
> because they just cause visual glitches. Leave "advanced" stuff like 
> choice of integer types until you have first understood the importance 
> of writing correct code.
>
Noow this really takes thee biscuit.

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


#83469 — Re: GCC hasn't even gotten around to sequencing argument evaluation

FromDavid Brown <david.brown@hesbynett.no>
Date2022-04-04 19:11 +0200
SubjectRe: GCC hasn't even gotten around to sequencing argument evaluation
Message-ID<t2f8sl$62t$1@dont-email.me>
In reply to#83461
On 04/04/2022 15:01, Malcolm McLean wrote:
> On Monday, 4 April 2022 at 12:29:00 UTC+1, David Brown wrote:
>> On 04/04/2022 11:07, Malcolm McLean wrote: 
>>
>>> Generally the processors primitive operations will wrap two's complement 
>>> arithmetic. So to raise a signal on overflow is more expensive rather 
>>> than less expensive.
>> "Generally" means "not always". For the very simple case of adding two 
>> numbers, wrapping is typically as efficient as UB on overflow. 
>> (Remember that wrapping is a perfectly acceptable "implementation" of 
>> UB.) Once you start including comparisons, or mixing types of different 
>> sizes, it is not always as simple.
>>
> If you wrap, you do not raise a signal. Generally this is cheaper than raising
> a signal because wrapping requires less circuitry than detecting overflow
> and raising  a signal. You've got it the wrong way round. Now if I was 
> arrongant and patronising like you, I'd say something arrrogant and
> patronising at this point.  

I don't think I am being "arrogant and patronising" - I am saying I
think you are showing a poor attitude to the importance of correct code,
are mistaken in what you consider to be possible consequences of certain
types of mistakes, and wrong about what might or might not be more
efficient in code generation.

Would it be "patronising" to point out that I said "Once you start
including comparisons, or mixing types of different sizes, it is not
always as simple", so discussions of the circuits used for an addition
are irrelevant?  Would it be "arrogant" to note that addition circuits
on most processors /always/ include overflow detection - because
sometimes these flags /are/ used, and it is cheaper in the circuitry to
generate that signal internally for every addition than to generate it
only sometimes?  (It would certainly be off-topic to do so, because
implementation circuitry is not relevant here.)


I don't intend to be either arrogant or patronising, but I do disagree
with some of your points and comments (while also agreeing with others).

>>
>>> Before we can write x = a * b, with signed integer types, we need to know 
>>> that the product will fit in x.
>> You also need that for unsigned types, if you are looking for a result 
>> that matches normal multiplication rather than modulo operations. (Just 
>> because arithmetic is fully defined for unsigned types, does not mean 
>> your results are always correct.)
> 
> You're repeating my points back to me, without realising that you are doing so.
> I've alreeady made the point that unsigned overflow is often worse. Because
> it is defined behaviour. You cannot get an exception.

It is not worse - it is much the same, in regard to the code itself.

You do not get an exception for unsigned overflow in C (or C++).

You do not get an exception for signed overflow in C (or C++).

In C (and C++), it is the duty of the programmer to ensure that there
will not be overflows in signed arithmetic, /before/ doing the
calculation.  How you do that, is up to you - there is no single "best"
method.

If you want your unsigned arithmetic to have the same results as for
normal mathematical integer arithmetic, rather than modulo arithmetic,
then you also need to ensure there is no overflow (or that the final
results are correct regardless of the overflow).  You can, if you want,
do this by determining the overflow /after/ the operation when dealing
with unsigned operations.

I'm sure you know all this, but I don't think you are expressing it well.

I'm sure you also know that "exception" is a term with a specific
meaning in C++, and that you do not get an exception for signed overflow
or unsigned overflow.

What you /can/ get, if you use appropriate tools and flags or options,
is debugging and testing help to cause some kind of debug output to be
produced for at least some cases of signed overflow.  And you /cannot/
get that for unsigned overflow - as you say, this is because it has
defined behaviour.  This is an advantage C and C++ have over, say, Java,
precisely because they have explicit undefined behaviour here.


>>> That's very burdensome, and most of the time 
>>> we know that a and b must be small. If a and b are read in from a user-supplied 
>>> file, the we don't know that, of course.
>> Then don't multiply them until you /do/ know. 
>>
>> Or make sure the user is aware that this is all "garbage in, garbage 
>> out" and it is their responsibility to provide valid data in the files 
>> and that your program makes no guarantees of correct or safe behaviour 
>> given invalid data.
>>
> That's a possibility. In fact you normally say that the software offers no
> guarantees of correct or safe behaviour undeer any circumstances.
> Liability is limited to the amount of money the customer paid for the
> software. You have no commeercial experience, obviously.

I /do/ have commercial experience.  I also have experience making
software where quality and correctness /is/ guaranteed, and where
reliable safe behaviour is a requirement.

I have plenty of experience writing code that will only work if the
inputs are valid, and nothing is even specified as to what might happen
if they are invalid.

What I do /not/ have experience in doing, is writing software where it
is acceptable to say "this data is not under our control, but we'll
assume it's safe" or "I know this code might be wrong but I can't be
bothered doing it correctly - probably no one will notice any mistakes".


>>
>> It can be good to write code in a way that allows certain classes of 
>> bugs to be turned into defined behaviour that guarantees an error 
>> message - "sanitizers" are useful development tools. But it is even 
>> better if you can find development processes that reduce the risk of 
>> bugs being written into the code, or increase their likelihood of being 
>> spotted early in the process. 
>>
> And it can be good to turn the undefined behaviour (by C++) of 
> integer overflow into the defined behaviour (by the compiler) of
> raising an exception. Then bugs are less likely to be serious. You
> show no ability to understand  this point.

That suggestion was not discussed (outside of its use for development
and debugging, where I explicitly recommended it), so I have given no
impression as to whether or not I might understand its benefit in
released code.  I /do/ understand it, and I agree that in some
circumstances it can make sense to have checks enabled even after
release.  I would rather handle this using appropriate C++ classes than
enabling it for /all/ integer arithmetic, since that would be hugely
inefficient.  (And if you want fully checked code and don't mind a
performance hit, there are other languages that might be better choices
than C++.)  Such classes would also let me raise C++ exceptions, rather
than whatever /you/ mean be "exception" here (I think you mean a signal
or trap).

>>
>> Start by eliminating the idea that you can be lazy about some mistakes 
>> because they just cause visual glitches. Leave "advanced" stuff like 
>> choice of integer types until you have first understood the importance 
>> of writing correct code.
>>
> Noow this really takes thee biscuit.
> 

Okay, I have to admit that /was/ patronising.  But I simply do not
accept your premise that it's fine to leave certain code full of
potential bugs just because you don't think the consequences are major.

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


Page 4 of 7 — ← Prev page 1 2 3 [4] 5 6 7  Next page →

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


csiph-web