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


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

two's complement idea

Started byBonita Montero <Bonita.Montero@gmail.com>
First post2019-11-04 20:48 +0100
Last post2020-02-26 02:22 +0000
Articles 20 on this page of 219 — 25 participants

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


Contents

  two's complement idea Bonita Montero <Bonita.Montero@gmail.com> - 2019-11-04 20:48 +0100
    Re: two's complement idea Bonita Montero <Bonita.Montero@gmail.com> - 2019-11-04 21:19 +0100
      Re: two's complement idea Öö Tiib <ootiib@hot.ee> - 2019-11-04 14:39 -0800
        Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2019-11-05 10:31 +0100
          Re: two's complement idea Bonita Montero <Bonita.Montero@gmail.com> - 2019-11-05 11:23 +0100
            Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2019-11-05 15:43 +0100
              Re: two's complement idea Bonita Montero <Bonita.Montero@gmail.com> - 2019-11-05 16:58 +0100
                Re: two's complement idea Paavo Helde <myfirstname@osa.pri.ee> - 2019-11-05 21:45 +0200
                  Re: two's complement idea Manfred <noname@add.invalid> - 2019-11-06 13:33 +0100
                    Re: two's complement idea Bonita Montero <Bonita.Montero@gmail.com> - 2019-11-06 13:51 +0100
                    Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2019-11-06 14:37 +0100
                      Re: two's complement idea Manfred <noname@add.invalid> - 2019-11-06 15:38 +0100
                        Re: two's complement idea Bonita Montero <Bonita.Montero@gmail.com> - 2019-11-06 15:53 +0100
                        Re: two's complement idea James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-11-06 10:06 -0500
                        Re: two's complement idea "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2019-11-06 17:00 +0100
                          Re: two's complement idea Manfred <noname@add.invalid> - 2019-11-06 17:47 +0100
                            Re: two's complement idea Bonita Montero <Bonita.Montero@gmail.com> - 2019-11-06 17:54 +0100
                              Re: two's complement idea Bo Persson <bo@bo-persson.se> - 2019-11-06 20:00 +0100
                                Re: two's complement idea Bonita Montero <Bonita.Montero@gmail.com> - 2019-11-06 20:13 +0100
                            Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2019-11-06 20:44 +0100
                        Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2019-11-06 20:36 +0100
                          Re: two's complement idea Manfred <noname@add.invalid> - 2019-11-06 22:54 +0100
                            Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2019-11-07 00:52 +0100
                    Re: two's complement idea Paavo Helde <myfirstname@osa.pri.ee> - 2019-11-06 17:54 +0200
                      Re: two's complement idea Manfred <noname@add.invalid> - 2019-11-06 18:15 +0100
                        Re: two's complement idea Bonita Montero <Bonita.Montero@gmail.com> - 2019-11-06 18:33 +0100
                        Re: two's complement idea Öö Tiib <ootiib@hot.ee> - 2019-11-06 10:55 -0800
                          Re: two's complement idea Bonita Montero <Bonita.Montero@gmail.com> - 2019-11-06 20:15 +0100
                          Re: two's complement idea Manfred <noname@add.invalid> - 2019-11-06 20:53 +0100
                            Re: two's complement idea Paavo Helde <myfirstname@osa.pri.ee> - 2019-11-06 22:25 +0200
                              Re: two's complement idea Manfred <noname@add.invalid> - 2019-11-06 23:05 +0100
                                Re: two's complement idea Paavo Helde <myfirstname@osa.pri.ee> - 2019-11-07 10:23 +0200
                            Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2019-11-06 22:20 +0100
                        Re: two's complement idea Paavo Helde <myfirstname@osa.pri.ee> - 2019-11-06 22:12 +0200
                  Re: two's complement idea Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-11-09 06:24 -0800
                    Re: two's complement idea Siri Cruise <chine.bleu@yahoo.com> - 2019-11-09 07:14 -0700
                    Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2019-11-10 11:52 +0100
                    Re: two's complement idea Paavo Helde <myfirstname@osa.pri.ee> - 2019-11-10 16:31 +0200
                      Re: two's complement idea Manfred <noname@invalid.add> - 2019-11-10 19:02 +0100
                        Re: two's complement idea Paavo Helde <myfirstname@osa.pri.ee> - 2019-11-11 12:08 +0200
                          Re: two's complement idea scott@slp53.sl.home (Scott Lurndal) - 2019-11-11 13:59 +0000
                            Re: two's complement idea Paavo Helde <myfirstname@osa.pri.ee> - 2019-11-11 17:09 +0200
                      Re: two's complement idea Richard Damon <Richard@Damon-Family.org> - 2019-11-18 07:40 -0500
                      Re: two's complement idea Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-11-28 12:27 -0800
                  Re: two's complement idea cdalten@gmail.com - 2020-01-24 05:39 -0800
                    Re: two's complement idea Paavo Helde <myfirstname@osa.pri.ee> - 2020-01-24 17:53 +0200
                      Re: two's complement idea Jorgen Grahn <grahn+nntp@snipabacken.se> - 2020-01-24 17:31 +0000
                Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2019-11-05 21:48 +0100
                  Re: two's complement idea Bonita Montero <Bonita.Montero@gmail.com> - 2019-11-06 07:08 +0100
                    Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2019-11-06 09:30 +0100
                      Re: two's complement idea Bonita Montero <Bonita.Montero@gmail.com> - 2019-11-06 09:57 +0100
          Re: two's complement idea Öö Tiib <ootiib@hot.ee> - 2019-11-05 09:02 -0800
            Re: two's complement idea scott@slp53.sl.home (Scott Lurndal) - 2019-11-05 17:15 +0000
              Re: two's complement idea Öö Tiib <ootiib@hot.ee> - 2019-11-05 10:19 -0800
            Re: two's complement idea Manfred <noname@invalid.add> - 2019-11-05 19:31 +0100
              Re: two's complement idea Öö Tiib <ootiib@hot.ee> - 2019-11-05 11:55 -0800
                Re: two's complement idea Manfred <noname@add.invalid> - 2019-11-05 22:48 +0100
                  Re: two's complement idea Öö Tiib <ootiib@hot.ee> - 2019-11-05 15:49 -0800
                  Re: two's complement idea Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-11-09 06:13 -0800
                    Re: two's complement idea Manfred <noname@invalid.add> - 2019-11-10 18:37 +0100
              Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2019-11-05 23:14 +0100
            Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2019-11-05 23:00 +0100
              Re: two's complement idea Öö Tiib <ootiib@hot.ee> - 2019-11-06 05:26 -0800
                Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2019-11-06 21:50 +0100
                  Re: two's complement idea Öö Tiib <ootiib@hot.ee> - 2019-11-08 02:01 -0800
                    Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2019-11-08 14:03 +0100
                      Re: two's complement idea Öö Tiib <ootiib@hot.ee> - 2019-11-08 12:08 -0800
                        Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2019-11-10 13:17 +0100
                          Re: two's complement idea "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2019-11-10 14:37 +0100
                            Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2019-11-10 17:08 +0100
                              Re: two's complement idea Manfred <noname@invalid.add> - 2019-11-10 18:34 +0100
                                Re: two's complement idea Ian Collins <ian-news@hotmail.com> - 2019-11-11 07:48 +1300
                                Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2019-11-10 21:31 +0100
    Re: two's complement idea Bo Persson <bo@bo-persson.se> - 2019-11-04 23:55 +0100
      Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2019-11-05 10:32 +0100
    Re: two's complement idea Siri Cruise <chine.bleu@yahoo.com> - 2019-11-04 19:55 -0700
      Re: two's complement idea "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2019-11-05 05:52 +0100
        Re: two's complement idea Ian Collins <ian-news@hotmail.com> - 2019-11-05 18:17 +1300
        Re: two's complement idea Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-11-09 05:55 -0800
          Re: two's complement idea Siri Cruise <chine.bleu@yahoo.com> - 2019-11-09 06:33 -0700
            Re: two's complement idea Öö Tiib <ootiib@hot.ee> - 2019-11-09 07:46 -0800
          Re: two's complement idea Öö Tiib <ootiib@hot.ee> - 2019-11-09 06:46 -0800
            Re: two's complement idea Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-11-28 12:19 -0800
              Re: two's complement idea "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2019-11-29 00:14 +0100
                Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2019-11-29 09:15 +0100
                  Re: two's complement idea Bo Persson <bo@bo-persson.se> - 2019-11-29 10:58 +0100
                    Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2019-11-29 12:49 +0100
                Re: two's complement idea Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-12-07 07:53 -0800
                  Re: two's complement idea Öö Tiib <ootiib@hot.ee> - 2019-12-07 08:22 -0800
                    Re: two's complement idea Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-01-10 20:44 -0800
                      Re: two's complement idea Öö Tiib <ootiib@hot.ee> - 2020-01-10 23:44 -0800
                        Re: two's complement idea Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-01-14 07:08 -0800
                          Re: two's complement idea Öö Tiib <ootiib@hot.ee> - 2020-01-14 08:42 -0800
                            Re: two's complement idea Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-01-21 02:09 -0800
                              Re: two's complement idea James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-01-21 05:14 -0800
                                Re: two's complement idea Daniel <danielaparker@gmail.com> - 2020-01-21 13:08 -0800
                                  Re: two's complement idea James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-01-22 00:07 -0500
                                  Re: two's complement idea Öö Tiib <ootiib@hot.ee> - 2020-01-21 23:21 -0800
                                    Re: two's complement idea Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-01-22 01:51 -0800
                                      Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2020-01-22 11:28 +0100
                                        Re: two's complement idea Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-22 11:52 +0100
                                        Re: two's complement idea Öö Tiib <ootiib@hot.ee> - 2020-01-22 04:47 -0800
                                Re: two's complement idea Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-04-02 07:19 -0700
                                  Re: two's complement idea James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-04-02 08:07 -0700
                              Re: two's complement idea boltar@nowhere.org - 2020-01-21 16:44 +0000
                                Re: two's complement idea Jorgen Grahn <grahn+nntp@snipabacken.se> - 2020-01-21 20:01 +0000
                                  Re: two's complement idea boltar@nowhere.org - 2020-01-22 11:26 +0000
                                    Re: two's complement idea Christian Gollwitzer <auriocus@gmx.de> - 2020-01-22 20:04 +0100
                                      Re: two's complement idea Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-01-22 11:30 -0800
                                      Re: two's complement idea Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2020-01-22 19:57 +0000
                                        Re: two's complement idea Ian Collins <ian-news@hotmail.com> - 2020-01-23 10:03 +1300
                                          Re: two's complement idea boltar@nowhere.org - 2020-01-23 09:24 +0000
                                            Re: two's complement idea Ian Collins <ian-news@hotmail.com> - 2020-01-24 07:29 +1300
                                      Re: two's complement idea Ian Collins <ian-news@hotmail.com> - 2020-01-23 10:03 +1300
                                      Re: two's complement idea "Fred. Zwarts" <F.Zwarts@KVI.nl> - 2020-01-23 10:09 +0100
                                        Re: two's complement idea boltar@nowhere.org - 2020-01-23 09:29 +0000
                                          Re: two's complement idea Bart <bc@freeuk.com> - 2020-01-24 01:08 +0000
                                            Re: two's complement idea boltar@nowhere.org - 2020-01-24 12:27 +0000
                                      Re: two's complement idea Bart <bc@freeuk.com> - 2020-01-24 01:06 +0000
                                        Re: two's complement idea Bo Persson <bo@bo-persson.se> - 2020-01-24 10:07 +0100
                                          Re: two's complement idea Paavo Helde <myfirstname@osa.pri.ee> - 2020-01-24 11:36 +0200
                                            Re: two's complement idea Öö Tiib <ootiib@hot.ee> - 2020-01-24 17:34 -0800
                                              Re: two's complement idea Siri Cruise <chine.bleu@yahoo.com> - 2020-01-24 17:57 -0800
                                          Re: two's complement idea Bart <bc@freeuk.com> - 2020-01-24 12:19 +0000
                                            Re: two's complement idea Bo Persson <bo@bo-persson.se> - 2020-01-24 14:19 +0100
                                              Re: two's complement idea Bart <bc@freeuk.com> - 2020-01-24 14:11 +0000
                                            Re: two's complement idea Jorgen Grahn <grahn+nntp@snipabacken.se> - 2020-01-24 17:26 +0000
                                              Re: two's complement idea Bart <bc@freeuk.com> - 2020-01-24 17:35 +0000
                                                Re: two's complement idea Paavo Helde <myfirstname@osa.pri.ee> - 2020-01-24 22:27 +0200
                                                  Re: two's complement idea James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-01-24 23:21 -0500
                                                Re: two's complement idea Ian Collins <ian-news@hotmail.com> - 2020-01-25 11:06 +1300
                                                Re: two's complement idea Jorgen Grahn <grahn+nntp@snipabacken.se> - 2020-01-24 22:12 +0000
                                                  Re: two's complement idea James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-01-24 23:24 -0500
                                                    Re: two's complement idea Jorgen Grahn <grahn+nntp@snipabacken.se> - 2020-01-25 09:04 +0000
                                                    Re: two's complement idea Öö Tiib <ootiib@hot.ee> - 2020-01-25 04:15 -0800
                                                    Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2020-01-25 19:55 +0100
                                            Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2020-01-25 00:05 +0100
                                              Re: two's complement idea Bart <bc@freeuk.com> - 2020-01-25 01:19 +0000
                                                Re: two's complement idea Ian Collins <ian-news@hotmail.com> - 2020-01-25 19:50 +1300
                                                  Re: two's complement idea Bart <bc@freeuk.com> - 2020-01-25 11:57 +0000
                                                    Re: two's complement idea Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2020-01-25 13:42 +0000
                                                      Re: two's complement idea Bart <bc@freeuk.com> - 2020-01-25 14:58 +0000
                                                        Re: two's complement idea Ian Collins <ian-news@hotmail.com> - 2020-01-26 07:58 +1300
                                                        Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2020-01-25 20:34 +0100
                                                        Re: two's complement idea Öö Tiib <ootiib@hot.ee> - 2020-01-25 12:41 -0800
                                                        Re: two's complement idea Paavo Helde <myfirstname@osa.pri.ee> - 2020-01-26 16:08 +0200
                                                          Re: two's complement idea Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-01-27 02:20 -0800
                                                            Re: two's complement idea Paavo Helde <myfirstname@osa.pri.ee> - 2020-01-27 15:03 +0200
                                                              Re: two's complement idea Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-02-15 06:44 -0800
                                                                Re: two's complement idea Paavo Helde <myfirstname@osa.pri.ee> - 2020-03-06 10:18 +0200
                                                                  Re: two's complement idea Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-04-02 07:05 -0700
                                                                    Re: two's complement idea Paavo Helde <myfirstname@osa.pri.ee> - 2020-04-02 20:03 +0300
                                                                      Re: two's complement idea Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-04-04 12:37 -0700
                                                    Re: two's complement idea Ian Collins <ian-news@hotmail.com> - 2020-01-26 07:45 +1300
                                                      Re: two's complement idea Bart <bc@freeuk.com> - 2020-01-25 19:56 +0000
                                                        Re: two's complement idea Ian Collins <ian-news@hotmail.com> - 2020-01-26 09:49 +1300
                                                          Re: two's complement idea Bart <bc@freeuk.com> - 2020-01-25 21:33 +0000
                                                            Re: two's complement idea Ian Collins <ian-news@hotmail.com> - 2020-01-26 11:00 +1300
                                                              Re: two's complement idea Bart <bc@freeuk.com> - 2020-01-25 22:23 +0000
                                                                Re: two's complement idea Ian Collins <ian-news@hotmail.com> - 2020-01-26 11:46 +1300
                                                                Re: two's complement idea Paavo Helde <myfirstname@osa.pri.ee> - 2020-01-26 10:55 +0200
                                                                  Re: two's complement idea Öö Tiib <ootiib@hot.ee> - 2020-01-26 03:47 -0800
                                                          Re: two's complement idea Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-01-27 01:28 -0800
                                                        Re: two's complement idea Jorgen Grahn <grahn+nntp@snipabacken.se> - 2020-01-25 22:22 +0000
                                                          Re: two's complement idea James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-01-25 18:24 -0500
                                                        Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2020-01-26 12:54 +0100
                                                          Re: two's complement idea Bart <bc@freeuk.com> - 2020-01-26 12:44 +0000
                                                            Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2020-01-26 14:58 +0100
                                                              Re: two's complement idea Bart <bc@freeuk.com> - 2020-01-26 14:53 +0000
                                                                Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2020-01-26 19:10 +0100
                                                                  Re: two's complement idea Robert Wessel <robertwessel2@yahoo.com> - 2020-01-26 13:20 -0600
                                                                    Re: two's complement idea Bart <bc@freeuk.com> - 2020-01-26 20:51 +0000
                                                                      Re: two's complement idea Robert Wessel <robertwessel2@yahoo.com> - 2020-01-26 21:02 -0600
                                                                        Re: two's complement idea Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-01-26 19:06 -0800
                                                                        Re: two's complement idea Bart <bc@freeuk.com> - 2020-01-27 18:50 +0000
                                                                          Re: two's complement idea Robert Wessel <robertwessel2@yahoo.com> - 2020-01-27 14:18 -0600
                                                                            Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2020-01-27 22:13 +0100
                                                                              Re: two's complement idea Bart <bc@freeuk.com> - 2020-01-27 21:38 +0000
                                                                                Re: two's complement idea Robert Wessel <robertwessel2@yahoo.com> - 2020-01-27 19:37 -0600
                                                                                  Re: two's complement idea Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-01-27 19:15 -0800
                                                                                Re: two's complement idea "Fred. Zwarts" <F.Zwarts@KVI.nl> - 2020-01-28 11:45 +0100
                                                                      Re: two's complement idea Ian Collins <ian-news@hotmail.com> - 2020-01-27 16:31 +1300
                                                              Re: two's complement idea Manfred <noname@add.invalid> - 2020-01-26 18:50 +0100
                                                                Re: two's complement idea Jorgen Grahn <grahn+nntp@snipabacken.se> - 2020-01-26 18:57 +0000
                                                                Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2020-01-26 20:46 +0100
                                                              Re: two's complement idea Robert Wessel <robertwessel2@yahoo.com> - 2020-01-26 13:14 -0600
                                                                Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2020-01-26 22:15 +0100
                                                                  Re: two's complement idea Robert Wessel <robertwessel2@yahoo.com> - 2020-01-27 21:06 -0600
                                                                    Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2020-01-28 13:08 +0100
                                                                Re: two's complement idea Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-01-27 01:50 -0800
                                                            Re: two's complement idea Ian Collins <ian-news@hotmail.com> - 2020-01-27 08:21 +1300
                                                    Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2020-01-25 20:14 +0100
                                                Re: two's complement idea David Brown <david.brown@hesbynett.no> - 2020-01-25 20:12 +0100
                                      Re: two's complement idea Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-01-27 07:48 -0800
                                      Re: two's complement idea Bonita Montero <Bonita.Montero@gmail.com> - 2020-02-18 18:46 +0100
          Re: two's complement idea Bonita Montero <Bonita.Montero@gmail.com> - 2019-11-09 17:03 +0100
      Re: two's complement idea Bonita Montero <Bonita.Montero@gmail.com> - 2019-11-05 06:56 +0100
        Re: two's complement idea Christian Gollwitzer <auriocus@gmx.de> - 2019-11-05 08:24 +0100
          Re: two's complement idea Bonita Montero <Bonita.Montero@gmail.com> - 2019-11-05 08:35 +0100
          Re: two's complement idea Öö Tiib <ootiib@hot.ee> - 2019-11-04 23:36 -0800
            Re: two's complement idea James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-11-05 09:19 -0500
    Re: two's complement idea Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-22 08:32 +0100
      Re: two's complement idea "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2020-01-22 09:23 +0100
        Re: two's complement idea Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-22 14:20 +0100
          Re: two's complement idea Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2020-01-22 13:37 +0000
        Re: two's complement idea Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-01-27 01:17 -0800
          Re: two's complement idea "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2020-01-27 12:35 +0100
            Re: two's complement idea Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-02-15 05:56 -0800
              Re: two's complement idea "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2020-02-16 09:17 +0100
                Re: two's complement idea Richard Damon <Richard@Damon-Family.org> - 2020-02-21 19:35 -0500
                  Re: two's complement idea "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2020-02-22 07:01 +0100
                Re: two's complement idea Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-02-24 08:22 -0800
        Re: two's complement idea cross@spitfire.i.gajendra.net (Dan Cross) - 2020-02-24 03:12 +0000
          Re: two's complement idea cdalten@gmail.com - 2020-02-24 05:53 -0800
          Re: two's complement idea Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-02-25 07:56 -0800
            Re: two's complement idea cross@spitfire.i.gajendra.net (Dan Cross) - 2020-02-25 22:00 +0000
              Re: two's complement idea Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-02-25 16:14 -0800
                Re: two's complement idea cdalten@gmail.com - 2020-02-25 18:18 -0800
                Re: two's complement idea cross@spitfire.i.gajendra.net (Dan Cross) - 2020-02-26 02:22 +0000

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


#69607

FromDavid Brown <david.brown@hesbynett.no>
Date2019-11-06 20:36 +0100
Message-ID<qpv7bt$v46$1@dont-email.me>
In reply to#69594
On 06/11/2019 15:38, Manfred wrote:
> On 11/6/2019 2:37 PM, David Brown wrote:
>> On 06/11/2019 13:33, Manfred wrote:
>>> On 11/5/2019 8:45 PM, Paavo Helde wrote:
>>>> On 5.11.2019 17:58, Bonita Montero wrote:
>>>>>
>>>>> With the same reasoning you could say that unsigneds might never
>>>>> wrap; but in fact they're specified to wrap.
>>>>
>>>> In retrospect, this (wrapping unsigneds) looks like a major design
>>>> mistake.
>>>
>>> No, it isn't.
>>>
>>>>
>>>> IMO, wrapping integers (signed or unsigned) are an example of
>>>> "optimization which nobody asked for", and they are there basically
>>>> only because the hardware happened to support such operations.
>>>>
>>>
>>> Look at the following code and see for yourself how efficient it is to
>>> check for integer overflow if unsigned integers do wrap.
>>> Achieving the same would be much more verbose (and less efficient) if
>>> unsigned overflow were not defined behavior.
>>>
>>> (taken from http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1969.htm)
>>>
>>> char* make_pathname (const char *dir, const char *fname, const char 
>>> *ext)
>>>    {
>>>        size_t dirlen = strlen (dir);
>>>        size_t filelen = strlen (fname);
>>>        size_t extlen = strlen (ext);
>>>
>>>        size_t pathlen = dirlen;
>>>
>>>        // detect and handle integer wrapping
>>>        if (   (pathlen += filelen) < filelen
>>>            || (pathlen += extlen) < extlen
>>>            || (pathlen += 3) < 3)
>>>            return 0;
>>
>> That is just silly, in all sorts of ways.
> 
> You realize that this comes from the glibc maintainers, don't you?

No.  But that doesn't change my opinion - at least not much.  It makes a 
bit more sense if it has to be portable to DOS, for example, with 16-bit 
size_t.

> You can say they wrote silly code for this example (I don't), but I 
> doubt there are many more knowledgeable people about this kind of matter 
> than them.
> 
> Moreover, I took this as an example of detection of integer overflow. 
> The fact that it happens to be about pathname strings is irrelevant to 
> this discussion.

It is, IMHO, a fine example of when overflow should not be issue - and 
that defined overflow behaviour is a lot less useful than many people think.

(I still agree that occasionally it is useful.)

> 
>>
>> First, decide if the function is an "internal" function where you can
>> trust the parameters, and have undefined behaviour if assumptions don't
>> hold, or an "external" function where you have to check the validity of
>> the parameters.
> 
> This example was written about code safety, so yes, I believe it is 
> pretty clear the assumption is that strings come from an external source.
> Obviously this applies to string /contents/; the pointer themselves can 
> only be internal to the program (can't they?), so no need to check for 
> null pointer.

I don't know the circumstances for this function, so I can't answer 
that.  But if it is an externally accessible function, I think checks 
for null pointers would make sense.

> On the other hand, contents of the string is checked by ensuring that 
> the result of strlen and their combination is valid. This is ensured 
> /exactly/ by making use of unsigned wrapping behavior.
> 

The code is going out of its way to check something that is almost 
impossible to occur, even with malicious intentions - while ignoring 
problems that could easily occur even by accident.

>>
>> If it is internal, you know the lengths of the passed strings will not
>> sum to more than 4G - or you don't care if someone does something
>> ridiculous.  (And on most modern systems, size_t is 64-bit - overflowing
>> here would require 16 EB ram for storing the strings.)
>>
>> If it is external, the checking is too little - if you have char*
>> pointers from an unknown source, you should be wary about running
>> strlen() on them because you don't know if it will actually end with a 0
>> in a reasonable limit.
> 
> This code handles C strings, so there is no way to check for their 
> length other than running strlen.

size_t limited_strlen(const char* s, size_t n) {
	const char* p = memchr(s, 0, n);
	if (!p) return (size_t) -1;		// Indicate bad string
	return p - s;
}

> The fact that you seem to miss is that it is exactly thanks to the check 
> that you call "silly" that it is ensured that they "actually end with a 
> 0 in a reasonable limit".

The checks don't do that.  If the three parameters pointed to strings 
adding up to 4 GB - 1 characters in total, by what stretch of the 
imagination is that "in a reasonable limit" ?

> 
> We could argue about what happens with /read/ access to a 
> non-0-terminated string, but I would simply assume that the strings are 
> 0 terminated, since the function is going to be called by some other 
> part of the program that can take care that there is a 0 at the end of 
> the buffer.

Failing to 0 terminate a character sequence that is intended to be a 
string is not an uncommon bug.

> What is not guaranteed is that the strings actually contain 
> pathnames, and don't contain very long malicious text instead (e.g. they 
> could come from stdin).

You need text sequences totalling more than 4 GB to cause a problem (and 
that's on older 32-bit size_t systems).  Since the user program can't 
have as much as 4 GB of data space, you'd need not only huge malicious 
texts, but you'd also need at least two of the three parameters to overlap.


> That risk is avoided by the code you call silly.
> So, no there is not too little checking.
> 
>>
>>
>> You only need to check for overflow if it is possible for the
>> calculations to overflow.  If the operands are too small to cause an
>> overflow, there will not be an overflow.
>>
>> And until you are talking about large integers for cryptography or that
>> sort of thing, adding up realistic numbers will not overflow a 64-bit 
>> type.
> 
> In fact cryptography is another example where unsigned wrap is useful, 
> but it would be much more complex (and off topic) to draw an example of 
> this (not that I claim to be an expert in this area)

Yes, I agree.  As I said, sometimes unsigned wrap is useful.  But not in 
this example.

> 
> And no, just assuming that "adding up realistic numbers will not 
> overflow a 64-bit type" is not what safe code is about.

Safe coding is never about assuming anything.  But safe coding involves 
looking at what values can occur (intentionally and unintentionally), 
and making checks /only/ when you need checks.  It involves /thinking/, 
rather than making checks in the blind "just in case".  And when you 
have 64-bit types, there are few non-specialist occasions when your 
values can overflow with simple addition.  If there is a risk of their 
being an overflow, then you probably have not sanity checked the values 
coming in.

> 
>>
>> So /if/ you have an old 32-bit size_t system, and /if/ you have
>> maliciously crafted parameters that point to huge strings (and you'll
>> have to make them point within the same string - you don't get over 4 GB
>> user memory address space with 32-bit size_t), then you can do your
>> adding up using 64-bit types and you get zero risk of overflow.
>>
>>
>>          uint_least64_t dirlen = strlen (dir);
>>          uint_least64_t filelen = strlen (fname);
>>          uint_least64_t extlen = strlen (ext);
>>
>>     uint_least64_t pathlen = dirlen + filelen + extlen;
>>
>>     if (big_size_t > MAX_SANE_PATHLENGTH) return 0;
> 
> You realize that this code is less efficient than the original one, 
> don't you?

You realise that it is /more/ efficient on any 64-bit system?  And that 
on 32-bit systems it is at most marginally less efficient, but might be 
more efficient (by avoiding branches)?  And that this code does 
something /useful/ by checking for a sensible maximum pathlength?  And 
that any few instruction cycles lost here are negligible compared to the 
hundreds that are needed for copying even a small path string?

> And what would be the correct value for MAX_SANE_PATHLENGTH? Are you 
> aware of the trouble that has been caused by Windows MAX_PATH?

You'd pick a big value for it - but a lot less than 4G.  Most 
filesystems limit file names to 255 bytes.  What would you say is a 
maximum depth of directories before it is clear that you have thoroughly 
screwed up somewhere - maybe 1000?  So pick MAX_SANE_PATHLENGTH at 256K 
on 32-bit systems, and 16M on 64-bit systems.  People with more 
knowledge of the target system in question can pick better values.

POSIX used to have a limit of 4096, which was okay in the old days but 
got a bit limiting.  Windows is limited to 32K now, which seems to be 
fine - the old limit was 260 characters which is clearly too small.

> 
> The example I posted achieves the same level of safety, using less 
> resources, and allowing for the maximum string length that the system 
> can /safely/ handle (don't miss the check after malloc). What more do 
> you want?

See what I wrote above.

> 
>>
>>
>> There are times when unsigned wrapping overflow is useful.  This is not
>> one of them.
>>
> 
> I suggest you read the code again (and its source - it is instructive)

I did.

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


#69615

FromManfred <noname@add.invalid>
Date2019-11-06 22:54 +0100
Message-ID<qpvfeu$3va$1@gioia.aioe.org>
In reply to#69607
On 11/6/2019 8:36 PM, David Brown wrote:
> On 06/11/2019 15:38, Manfred wrote:
>> On 11/6/2019 2:37 PM, David Brown wrote:
>>> On 06/11/2019 13:33, Manfred wrote:
>>>> On 11/5/2019 8:45 PM, Paavo Helde wrote:
>>>>> On 5.11.2019 17:58, Bonita Montero wrote:
>>>>>>
>>>>>> With the same reasoning you could say that unsigneds might never
>>>>>> wrap; but in fact they're specified to wrap.
>>>>>
>>>>> In retrospect, this (wrapping unsigneds) looks like a major design
>>>>> mistake.
>>>>
>>>> No, it isn't.
>>>>
>>>>>
>>>>> IMO, wrapping integers (signed or unsigned) are an example of
>>>>> "optimization which nobody asked for", and they are there basically
>>>>> only because the hardware happened to support such operations.
>>>>>
>>>>
>>>> Look at the following code and see for yourself how efficient it is to
>>>> check for integer overflow if unsigned integers do wrap.
>>>> Achieving the same would be much more verbose (and less efficient) if
>>>> unsigned overflow were not defined behavior.
>>>>
>>>> (taken from http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1969.htm)
>>>>
>>>> char* make_pathname (const char *dir, const char *fname, const char 
>>>> *ext)
>>>>    {
>>>>        size_t dirlen = strlen (dir);
>>>>        size_t filelen = strlen (fname);
>>>>        size_t extlen = strlen (ext);
>>>>
>>>>        size_t pathlen = dirlen;
>>>>
>>>>        // detect and handle integer wrapping
>>>>        if (   (pathlen += filelen) < filelen
>>>>            || (pathlen += extlen) < extlen
>>>>            || (pathlen += 3) < 3)
>>>>            return 0;
>>>
>>> That is just silly, in all sorts of ways.
>>
>> You realize that this comes from the glibc maintainers, don't you?
> 
> No.  But that doesn't change my opinion - at least not much.  It makes a 
> bit more sense if it has to be portable to DOS, for example, with 16-bit 
> size_t.
> 
>> You can say they wrote silly code for this example (I don't), but I 
>> doubt there are many more knowledgeable people about this kind of 
>> matter than them.

[...]

>>>
>>> First, decide if the function is an "internal" function where you can
>>> trust the parameters, and have undefined behaviour if assumptions don't
>>> hold, or an "external" function where you have to check the validity of
>>> the parameters.
>>
>> This example was written about code safety, so yes, I believe it is 
>> pretty clear the assumption is that strings come from an external source.
>> Obviously this applies to string /contents/; the pointer themselves 
>> can only be internal to the program (can't they?), so no need to check 
>> for null pointer.
> 
> I don't know the circumstances for this function, so I can't answer 
> that.  But if it is an externally accessible function, I think checks 
> for null pointers would make sense.

I think there is some misunderstanding about what we mean for "external" 
here, and below.
This is an example of application code, in the context of code safety, 
that may be written as part of the final program or as part of a 
library. Either way, the pointers are in control of the programmer who 
writes the program, and he does not want to pass null pointers here.

Yes, this may happen if there is a mistake somewhere in the program, but 
this is not what code safety is about, it is about code correctness, 
which is a somewhat different thing (although it is true that incorrect 
code is almost certainly unsafe code as well).
It is for this reason that standard library functions do not check for 
null on all pointers passed in, and I am sure you don't check for null 
within every function you write.
Code safety as I understand it is about ensuring the program works as 
expected with every kind of data input that is supplied to the /program/ 
- like through an I/O stream (kernel safety is a different matter of 
course).
In other words, when you read from std::cin, a file or a socket, you 
allocate a buffer and you know that its pointer is valid. When you reach 
EOF you also know that the buffer is 0-terminated - you place a 0 
yourself if the runtime does not do this for you.

What you don't know (you can't control it) is if the /contents/ between 
the pointer address and the terminating 0 has a valid format, whether it 
is too large or whatever, and that's what you need to ensure that your 
program is robust against in order to be safe.

> 
>> On the other hand, contents of the string is checked by ensuring that 
>> the result of strlen and their combination is valid. This is ensured 
>> /exactly/ by making use of unsigned wrapping behavior.
>>
> 
> The code is going out of its way to check something that is almost 
> impossible to occur, even with malicious intentions - while ignoring 
> problems that could easily occur even by accident.
See above.

> 
>>>
>>> If it is internal, you know the lengths of the passed strings will not
>>> sum to more than 4G - or you don't care if someone does something
>>> ridiculous.  (And on most modern systems, size_t is 64-bit - overflowing
>>> here would require 16 EB ram for storing the strings.)
>>>
>>> If it is external, the checking is too little - if you have char*
>>> pointers from an unknown source, you should be wary about running
>>> strlen() on them because you don't know if it will actually end with a 0
>>> in a reasonable limit.
>>
>> This code handles C strings, so there is no way to check for their 
>> length other than running strlen.
> 
> size_t limited_strlen(const char* s, size_t n) {
>      const char* p = memchr(s, 0, n);
>      if (!p) return (size_t) -1;        // Indicate bad string
>      return p - s;
> }

Incidentally, this takes a (pointer, length) pair, which is not a C string.
But that's irrelevant, I explained above that the presence of the 
terminating 0 can and needs to be ensured at the calling level.

> 
>> The fact that you seem to miss is that it is exactly thanks to the 
>> check that you call "silly" that it is ensured that they "actually end 
>> with a 0 in a reasonable limit".
> 
> The checks don't do that.  If the three parameters pointed to strings 
> adding up to 4 GB - 1 characters in total, by what stretch of the 
> imagination is that "in a reasonable limit" ?

Define reasonable.
The checks ensure that the code will concat correctly whatever length 
can be /safely/ handled by the system, and handle correctly excessive 
lengths as well, thus covering the entire input domain. That's enough 
for safety, with no need to introduce any dependency on an additional 
and arbitrary parameter.

> 
>>
>> We could argue about what happens with /read/ access to a 
>> non-0-terminated string, but I would simply assume that the strings 
>> are 0 terminated, since the function is going to be called by some 
>> other part of the program that can take care that there is a 0 at the 
>> end of the buffer.
> 
> Failing to 0 terminate a character sequence that is intended to be a 
> string is not an uncommon bug.
See above.

> 
>> What is not guaranteed is that the strings actually contain pathnames, 
>> and don't contain very long malicious text instead (e.g. they could 
>> come from stdin).
> 
> You need text sequences totalling more than 4 GB to cause a problem (and 
> that's on older 32-bit size_t systems).  Since the user program can't 
> have as much as 4 GB of data space, you'd need not only huge malicious 
> texts, but you'd also need at least two of the three parameters to overlap.
> 
> 
>> That risk is avoided by the code you call silly.
>> So, no there is not too little checking.
>>
>>>
>>>
>>> You only need to check for overflow if it is possible for the
>>> calculations to overflow.  If the operands are too small to cause an
>>> overflow, there will not be an overflow.
>>>
Yes, keep "if the operands are too small" in mind, and see below.

[...]

>>
>>>
>>> So /if/ you have an old 32-bit size_t system, and /if/ you have
>>> maliciously crafted parameters that point to huge strings (and you'll
>>> have to make them point within the same string - you don't get over 4 GB
>>> user memory address space with 32-bit size_t), then you can do your
>>> adding up using 64-bit types and you get zero risk of overflow.
>>>
>>>
>>>          uint_least64_t dirlen = strlen (dir);
>>>          uint_least64_t filelen = strlen (fname);
>>>          uint_least64_t extlen = strlen (ext);
>>>
>>>     uint_least64_t pathlen = dirlen + filelen + extlen;
>>>
>>>     if (big_size_t > MAX_SANE_PATHLENGTH) return 0;
>>
>> You realize that this code is less efficient than the original one, 
>> don't you?
> 
> You realise that it is /more/ efficient on any 64-bit system?

Watch out: you wrote this example for 32-bit, but on 64 bit it can fail 
for large enough inputs:

         // the following /can/ now silently overflow
 >>>     uint_least64_t pathlen = dirlen + filelen + extlen;
 >>>
 >>>     if (big_size_t > MAX_SANE_PATHLENGTH) return 0;

That is, on 64-bit it becomes unsafe.

   And that
> on 32-bit systems it is at most marginally less efficient, but might be 
> more efficient (by avoiding branches)?  And that this code does 
> something /useful/ by checking for a sensible maximum pathlength?  And 
> that any few instruction cycles lost here are negligible compared to the 
> hundreds that are needed for copying even a small path string?
As I wrote elsethread, if you are on 32-bit, and cast to 64-bit you 
don't really solve the problem, you move it ahead - in other words, you 
can't think of handling integer overflow by assuming you always have a 
wider type available.
Remember, the topic here is about unsigned wrapping, i.e. integer overflow.

However, without avoiding your point, your alternative works under some 
conditions, but it is more wasteful of resources (and as a programmer 
involved with microcontrollers and embedded software you are sensible to 
this matter), I don't see the benefit of an arbitratry 
MAX_SANE_PATHLENGTH - in fact I'd rather not bother about any, and I 
don't see how it would be any better than the original.

> 
>> And what would be the correct value for MAX_SANE_PATHLENGTH? Are you 
>> aware of the trouble that has been caused by Windows MAX_PATH?
> 
> You'd pick a big value for it - but a lot less than 4G.  Most 
> filesystems limit file names to 255 bytes.  What would you say is a 
> maximum depth of directories before it is clear that you have thoroughly 
> screwed up somewhere - maybe 1000?  So pick MAX_SANE_PATHLENGTH at 256K 
> on 32-bit systems, and 16M on 64-bit systems.  People with more 
> knowledge of the target system in question can pick better values.
> 
> POSIX used to have a limit of 4096, which was okay in the old days but 
> got a bit limiting.  Windows is limited to 32K now, which seems to be 
> fine - the old limit was 260 characters which is clearly too small.
> 
>>
>> The example I posted achieves the same level of safety, using less 
>> resources, and allowing for the maximum string length that the system 
>> can /safely/ handle (don't miss the check after malloc). What more do 
>> you want?
> 
> See what I wrote above.
> 
>>
>>>
>>>
>>> There are times when unsigned wrapping overflow is useful.  This is not
>>> one of them.
>>>
>>
>> I suggest you read the code again (and its source - it is instructive)
> 
> I did.

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


#69617

FromDavid Brown <david.brown@hesbynett.no>
Date2019-11-07 00:52 +0100
Message-ID<qpvmcc$n51$1@dont-email.me>
In reply to#69615
On 06/11/2019 22:54, Manfred wrote:
> On 11/6/2019 8:36 PM, David Brown wrote:
>> On 06/11/2019 15:38, Manfred wrote:
>>> On 11/6/2019 2:37 PM, David Brown wrote:
>>>> On 06/11/2019 13:33, Manfred wrote:
>>>>> On 11/5/2019 8:45 PM, Paavo Helde wrote:
>>>>>> On 5.11.2019 17:58, Bonita Montero wrote:
>>>>>>>
>>>>>>> With the same reasoning you could say that unsigneds might never
>>>>>>> wrap; but in fact they're specified to wrap.
>>>>>>
>>>>>> In retrospect, this (wrapping unsigneds) looks like a major design
>>>>>> mistake.
>>>>>
>>>>> No, it isn't.
>>>>>
>>>>>>
>>>>>> IMO, wrapping integers (signed or unsigned) are an example of
>>>>>> "optimization which nobody asked for", and they are there basically
>>>>>> only because the hardware happened to support such operations.
>>>>>>
>>>>>
>>>>> Look at the following code and see for yourself how efficient it is to
>>>>> check for integer overflow if unsigned integers do wrap.
>>>>> Achieving the same would be much more verbose (and less efficient) if
>>>>> unsigned overflow were not defined behavior.
>>>>>
>>>>> (taken from http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1969.htm)
>>>>>
>>>>> char* make_pathname (const char *dir, const char *fname, const char 
>>>>> *ext)
>>>>>    {
>>>>>        size_t dirlen = strlen (dir);
>>>>>        size_t filelen = strlen (fname);
>>>>>        size_t extlen = strlen (ext);
>>>>>
>>>>>        size_t pathlen = dirlen;
>>>>>
>>>>>        // detect and handle integer wrapping
>>>>>        if (   (pathlen += filelen) < filelen
>>>>>            || (pathlen += extlen) < extlen
>>>>>            || (pathlen += 3) < 3)
>>>>>            return 0;
>>>>
>>>> That is just silly, in all sorts of ways.
>>>
>>> You realize that this comes from the glibc maintainers, don't you?
>>
>> No.  But that doesn't change my opinion - at least not much.  It makes 
>> a bit more sense if it has to be portable to DOS, for example, with 
>> 16-bit size_t.
>>
>>> You can say they wrote silly code for this example (I don't), but I 
>>> doubt there are many more knowledgeable people about this kind of 
>>> matter than them.
> 
> [...]
> 
>>>>
>>>> First, decide if the function is an "internal" function where you can
>>>> trust the parameters, and have undefined behaviour if assumptions don't
>>>> hold, or an "external" function where you have to check the validity of
>>>> the parameters.
>>>
>>> This example was written about code safety, so yes, I believe it is 
>>> pretty clear the assumption is that strings come from an external 
>>> source.
>>> Obviously this applies to string /contents/; the pointer themselves 
>>> can only be internal to the program (can't they?), so no need to 
>>> check for null pointer.
>>
>> I don't know the circumstances for this function, so I can't answer 
>> that.  But if it is an externally accessible function, I think checks 
>> for null pointers would make sense.
> 
> I think there is some misunderstanding about what we mean for "external" 
> here, and below.
> This is an example of application code, in the context of code safety, 
> that may be written as part of the final program or as part of a 
> library. Either way, the pointers are in control of the programmer who 
> writes the program, and he does not want to pass null pointers here.
> 

That would make it an internal function, not an external function. 
Checking for absurd string lengths (and therefore the overflow) is thus 
unnecessary.

> Yes, this may happen if there is a mistake somewhere in the program, but 
> this is not what code safety is about, it is about code correctness, 
> which is a somewhat different thing (although it is true that incorrect 
> code is almost certainly unsafe code as well).
> It is for this reason that standard library functions do not check for 
> null on all pointers passed in, and I am sure you don't check for null 
> within every function you write.

I also don't check sizes, ranges, etc., because my functions are all 
internal (since I code for small embedded systems, not libraries). 
Functions have a defined set of values that are valid for their 
parameters - and they can assume those rules are upheld (baring program 
bugs, as you say).

> Code safety as I understand it is about ensuring the program works as 
> expected with every kind of data input that is supplied to the /program/ 
> - like through an I/O stream (kernel safety is a different matter of 
> course).

Correct.

> In other words, when you read from std::cin, a file or a socket, you 
> allocate a buffer and you know that its pointer is valid. When you reach 
> EOF you also know that the buffer is 0-terminated - you place a 0 
> yourself if the runtime does not do this for you.
> 
> What you don't know (you can't control it) is if the /contents/ between 
> the pointer address and the terminating 0 has a valid format, whether it 
> is too large or whatever, and that's what you need to ensure that your 
> program is robust against in order to be safe.

Agreed.  So you check it for validity.  4 GB path strings are not valid 
input.  You don't need to check for overflow on the sum of the lengths - 
you need to check that the data is sane.

> 
>>
>>> On the other hand, contents of the string is checked by ensuring that 
>>> the result of strlen and their combination is valid. This is ensured 
>>> /exactly/ by making use of unsigned wrapping behavior.
>>>
>>
>> The code is going out of its way to check something that is almost 
>> impossible to occur, even with malicious intentions - while ignoring 
>> problems that could easily occur even by accident.
> See above.
> 
>>
>>>>
>>>> If it is internal, you know the lengths of the passed strings will not
>>>> sum to more than 4G - or you don't care if someone does something
>>>> ridiculous.  (And on most modern systems, size_t is 64-bit - 
>>>> overflowing
>>>> here would require 16 EB ram for storing the strings.)
>>>>
>>>> If it is external, the checking is too little - if you have char*
>>>> pointers from an unknown source, you should be wary about running
>>>> strlen() on them because you don't know if it will actually end with 
>>>> a 0
>>>> in a reasonable limit.
>>>
>>> This code handles C strings, so there is no way to check for their 
>>> length other than running strlen.
>>
>> size_t limited_strlen(const char* s, size_t n) {
>>      const char* p = memchr(s, 0, n);
>>      if (!p) return (size_t) -1;        // Indicate bad string
>>      return p - s;
>> }
> 
> Incidentally, this takes a (pointer, length) pair, which is not a C string.

It is checking that the non-null const char * pointer points to a C 
string of no greater than n in length.  It will return a failure 
indication if that is not the case (without bothering to check if it is 
a C string that is too long, or if it is not a string at all).

> But that's irrelevant, I explained above that the presence of the 
> terminating 0 can and needs to be ensured at the calling level.

The checks need to be made somewhere.  I don't know where this function 
fits in the scheme of things, so I don't know whether it makes sense to 
check in the function, or check before calling the function.  But I do 
know that calculating the strlen values and checking for overflow on 
adding them fails to check for real problems if checks are needed, and 
is redundant if checks are not needed.

> 
>>
>>> The fact that you seem to miss is that it is exactly thanks to the 
>>> check that you call "silly" that it is ensured that they "actually 
>>> end with a 0 in a reasonable limit".
>>
>> The checks don't do that.  If the three parameters pointed to strings 
>> adding up to 4 GB - 1 characters in total, by what stretch of the 
>> imagination is that "in a reasonable limit" ?
> 
> Define reasonable.

That is the job of the person specifying the function.

> The checks ensure that the code will concat correctly whatever length 
> can be /safely/ handled by the system, and handle correctly excessive 
> lengths as well, thus covering the entire input domain. That's enough 
> for safety, with no need to introduce any dependency on an additional 
> and arbitrary parameter.

Nonsense.  4 GB path strings - and 16 EB path strings on 64-bit systems 
- cannot be handled safely by the system.  They might be blocked by 
something further down the chain of calls, but you are not going to 
persuade anyone that 4 GB path strings are sensible and can be used 
safely for the purpose of dealing with files.

> 
>>
>>>
>>> We could argue about what happens with /read/ access to a 
>>> non-0-terminated string, but I would simply assume that the strings 
>>> are 0 terminated, since the function is going to be called by some 
>>> other part of the program that can take care that there is a 0 at the 
>>> end of the buffer.
>>
>> Failing to 0 terminate a character sequence that is intended to be a 
>> string is not an uncommon bug.
> See above.
> 
>>
>>> What is not guaranteed is that the strings actually contain 
>>> pathnames, and don't contain very long malicious text instead (e.g. 
>>> they could come from stdin).
>>
>> You need text sequences totalling more than 4 GB to cause a problem 
>> (and that's on older 32-bit size_t systems).  Since the user program 
>> can't have as much as 4 GB of data space, you'd need not only huge 
>> malicious texts, but you'd also need at least two of the three 
>> parameters to overlap.
>>
>>
>>> That risk is avoided by the code you call silly.
>>> So, no there is not too little checking.
>>>
>>>>
>>>>
>>>> You only need to check for overflow if it is possible for the
>>>> calculations to overflow.  If the operands are too small to cause an
>>>> overflow, there will not be an overflow.
>>>>
> Yes, keep "if the operands are too small" in mind, and see below.
> 
> [...]
> 
>>>
>>>>
>>>> So /if/ you have an old 32-bit size_t system, and /if/ you have
>>>> maliciously crafted parameters that point to huge strings (and you'll
>>>> have to make them point within the same string - you don't get over 
>>>> 4 GB
>>>> user memory address space with 32-bit size_t), then you can do your
>>>> adding up using 64-bit types and you get zero risk of overflow.
>>>>
>>>>
>>>>          uint_least64_t dirlen = strlen (dir);
>>>>          uint_least64_t filelen = strlen (fname);
>>>>          uint_least64_t extlen = strlen (ext);
>>>>
>>>>     uint_least64_t pathlen = dirlen + filelen + extlen;
>>>>
>>>>     if (big_size_t > MAX_SANE_PATHLENGTH) return 0;
>>>
>>> You realize that this code is less efficient than the original one, 
>>> don't you?
>>
>> You realise that it is /more/ efficient on any 64-bit system?
> 
> Watch out: you wrote this example for 32-bit, but on 64 bit it can fail 
> for large enough inputs:
> 
>          // the following /can/ now silently overflow
>  >>>     uint_least64_t pathlen = dirlen + filelen + extlen;
>  >>>
>  >>>     if (big_size_t > MAX_SANE_PATHLENGTH) return 0;
> 
> That is, on 64-bit it becomes unsafe.

I know exactly what I wrote.  And I know that it is safe - because you 
won't get overflow until strlen has finished counting these 16 PB long 
strings, and the earth has melted into the dying sun.

> 
>    And that
>> on 32-bit systems it is at most marginally less efficient, but might 
>> be more efficient (by avoiding branches)?  And that this code does 
>> something /useful/ by checking for a sensible maximum pathlength?  And 
>> that any few instruction cycles lost here are negligible compared to 
>> the hundreds that are needed for copying even a small path string?
> As I wrote elsethread, if you are on 32-bit, and cast to 64-bit you 
> don't really solve the problem, you move it ahead - in other words, you 
> can't think of handling integer overflow by assuming you always have a 
> wider type available.
> Remember, the topic here is about unsigned wrapping, i.e. integer overflow.

And I have been demonstrating how it is not appropriate in your example 
- it is neither necessary nor sufficient.

> 
> However, without avoiding your point, your alternative works under some 
> conditions, but it is more wasteful of resources (and as a programmer 
> involved with microcontrollers and embedded software you are sensible to 
> this matter), I don't see the benefit of an arbitratry 
> MAX_SANE_PATHLENGTH - in fact I'd rather not bother about any, and I 
> don't see how it would be any better than the original.
> 

Sorry, but my solution is /not/ wasteful of resources on a realistic 
system - it is more efficient for 64-bit systems.

(You would be unlikely to have such a function on a small 
microcontroller, and you know your limits on such a system - you would 
not need to check for overflow.)

>>
>>> And what would be the correct value for MAX_SANE_PATHLENGTH? Are you 
>>> aware of the trouble that has been caused by Windows MAX_PATH?
>>
>> You'd pick a big value for it - but a lot less than 4G.  Most 
>> filesystems limit file names to 255 bytes.  What would you say is a 
>> maximum depth of directories before it is clear that you have 
>> thoroughly screwed up somewhere - maybe 1000?  So pick 
>> MAX_SANE_PATHLENGTH at 256K on 32-bit systems, and 16M on 64-bit 
>> systems.  People with more knowledge of the target system in question 
>> can pick better values.
>>
>> POSIX used to have a limit of 4096, which was okay in the old days but 
>> got a bit limiting.  Windows is limited to 32K now, which seems to be 
>> fine - the old limit was 260 characters which is clearly too small.
>>
>>>
>>> The example I posted achieves the same level of safety, using less 
>>> resources, and allowing for the maximum string length that the system 
>>> can /safely/ handle (don't miss the check after malloc). What more do 
>>> you want?
>>
>> See what I wrote above.
>>
>>>
>>>>
>>>>
>>>> There are times when unsigned wrapping overflow is useful.  This is not
>>>> one of them.
>>>>
>>>
>>> I suggest you read the code again (and its source - it is instructive)
>>
>> I did.
> 

Then let's leave it there.  I don't think there is much to be gained by 
continuing in this line.

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


#69597

FromPaavo Helde <myfirstname@osa.pri.ee>
Date2019-11-06 17:54 +0200
Message-ID<qpuqci$f5e$1@dont-email.me>
In reply to#69589
On 6.11.2019 14:33, Manfred wrote:
> On 11/5/2019 8:45 PM, Paavo Helde wrote:
>> On 5.11.2019 17:58, Bonita Montero wrote:
>>>
>>> With the same reasoning you could say that unsigneds might never
>>> wrap; but in fact they're specified to wrap.
>>
>> In retrospect, this (wrapping unsigneds) looks like a major design
>> mistake.
>
> No, it isn't.
>
>>
>> IMO, wrapping integers (signed or unsigned) are an example of
>> "optimization which nobody asked for", and they are there basically
>> only because the hardware happened to support such operations.
>>
>
> Look at the following code and see for yourself how efficient it is to
> check for integer overflow if unsigned integers do wrap.
> Achieving the same would be much more verbose (and less efficient) if
> unsigned overflow were not defined behavior.
>
> (taken from http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1969.htm)
>
> char* make_pathname (const char *dir, const char *fname, const char *ext)
>    {
>        size_t dirlen = strlen (dir);
>        size_t filelen = strlen (fname);
>        size_t extlen = strlen (ext);
>
>        size_t pathlen = dirlen;
>
>        // detect and handle integer wrapping
>        if (   (pathlen += filelen) < filelen
>            || (pathlen += extlen) < extlen
>            || (pathlen += 3) < 3)
>            return 0;
>
>        char *p, *path = malloc (pathlen);
>        if (!path)
>            return 0;
>
>        p = memcpy (path, dir, dirlen);
>        p [dirlen] = '/';
>
>        p = memcpy (p + dirlen + 1, fname, filelen);
>        p [filelen] = '.';
>
>        memcpy (p + filelen + 1, ext, extlen + 1);
>
>        return path;
>    }

Seriously?

std::string make_pathname(const std::string& dir,
	const std::string& fname, const std::string& ext)
{
	return dir + "/" + fname + "." + ext;
}

No need to check for any overflows.

Not to speak about that there cannot be overflow in the first place 
because if pathlen overflows the three strings dir, fname and ext would 
not fit in the process memory anyway.

Not to speak about that the time lost for a more explicit check for 
overflow would be zero or unmeasurable, compared to any file access 
itself, or even when compared to the malloc() call in the same function.

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


#69601

FromManfred <noname@add.invalid>
Date2019-11-06 18:15 +0100
Message-ID<qpuv49$1mgn$1@gioia.aioe.org>
In reply to#69597
On 11/6/2019 4:54 PM, Paavo Helde wrote:
> On 6.11.2019 14:33, Manfred wrote:
>> On 11/5/2019 8:45 PM, Paavo Helde wrote:
>>> On 5.11.2019 17:58, Bonita Montero wrote:
>>>>
>>>> With the same reasoning you could say that unsigneds might never
>>>> wrap; but in fact they're specified to wrap.
>>>
>>> In retrospect, this (wrapping unsigneds) looks like a major design
>>> mistake.
>>
>> No, it isn't.
>>
>>>
>>> IMO, wrapping integers (signed or unsigned) are an example of
>>> "optimization which nobody asked for", and they are there basically
>>> only because the hardware happened to support such operations.
>>>
>>
>> Look at the following code and see for yourself how efficient it is to
>> check for integer overflow if unsigned integers do wrap.
>> Achieving the same would be much more verbose (and less efficient) if
>> unsigned overflow were not defined behavior.
>>
>> (taken from http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1969.htm)
>>
>> char* make_pathname (const char *dir, const char *fname, const char *ext)
>>    {
>>        size_t dirlen = strlen (dir);
>>        size_t filelen = strlen (fname);
>>        size_t extlen = strlen (ext);
>>
>>        size_t pathlen = dirlen;
>>
>>        // detect and handle integer wrapping
>>        if (   (pathlen += filelen) < filelen
>>            || (pathlen += extlen) < extlen
>>            || (pathlen += 3) < 3)
>>            return 0;
>>
>>        char *p, *path = malloc (pathlen);
>>        if (!path)
>>            return 0;
>>
>>        p = memcpy (path, dir, dirlen);
>>        p [dirlen] = '/';
>>
>>        p = memcpy (p + dirlen + 1, fname, filelen);
>>        p [filelen] = '.';
>>
>>        memcpy (p + filelen + 1, ext, extlen + 1);
>>
>>        return path;
>>    }
> 
> Seriously?
> 
> std::string make_pathname(const std::string& dir,
>      const std::string& fname, const std::string& ext)
> {
>      return dir + "/" + fname + "." + ext;
> }
> 
> No need to check for any overflows.

How do you think that overflow check is done inside std::string?

> 
> Not to speak about that there cannot be overflow in the first place 
> because if pathlen overflows the three strings dir, fname and ext would 
> not fit in the process memory anyway.
> 
> Not to speak about that the time lost for a more explicit check for 
> overflow would be zero or unmeasurable, compared to any file access 
> itself, or even when compared to the malloc() call in the same function.
> 
> 

What do you mean with "more explicit check for overflow"?

Assuming you know the variables are 32-bit unsigned, I suppose you could do
if (pathlen < 0xFFFFFFFF-filelen)
{
   pathlen += filelen;
}
else
{
   return 0;
}

and then repeat, but honestly I don't see the benefit of it compared to 
the above (as a first you are introducing a dependency on the specific 
integer size).
Or you can cast to a wider type, but then you are not solving the 
problem, you are only moving it forward, and still I wouldn't see the 
benefit.

Besides, this is about /integer/ overflow check, so it could apply to 
more computations other than memory size.

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


#69602

FromBonita Montero <Bonita.Montero@gmail.com>
Date2019-11-06 18:33 +0100
Message-ID<qpv05f$nvc$1@news.albasani.net>
In reply to#69601
> What do you mean with "more explicit check for overflow"?

concatenating strings in C++ with the + opereator is reliable.

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


#69603

FromÖö Tiib <ootiib@hot.ee>
Date2019-11-06 10:55 -0800
Message-ID<cf4a4cc6-a3a3-4697-b870-313c067be68e@googlegroups.com>
In reply to#69601
On Wednesday, 6 November 2019 19:16:08 UTC+2, Manfred  wrote:
> On 11/6/2019 4:54 PM, Paavo Helde wrote:
> > Seriously?
> > 
> > std::string make_pathname(const std::string& dir,
> >      const std::string& fname, const std::string& ext)
> > {
> >      return dir + "/" + fname + "." + ext;
> > }
> > 
> > No need to check for any overflows.
> 
> How do you think that overflow check is done inside std::string?

All standard library writers are rather good programmers.
Obviously they have something that is easy to read from afar that it does
no way overflow. Likely it is some short inline member to call
when size is supposed to grow that does the check:

    if (max_size() - size() < size_to_add) 
        throw std::length_error(text_to_throw);

Why don't you look into any of implementations in your computer?

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


#69606

FromBonita Montero <Bonita.Montero@gmail.com>
Date2019-11-06 20:15 +0100
Message-ID<qpv657$8rg$2@news.albasani.net>
In reply to#69603
> All standard library writers are rather good programmers.

Another aspect is: if millions of developers reuse code instead of
writing it on their own, errors will be noticed for sure; but when
you do everything yourself, a lot of errors won't be noticed.

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


#69609

FromManfred <noname@add.invalid>
Date2019-11-06 20:53 +0100
Message-ID<qpv8ca$12a1$1@gioia.aioe.org>
In reply to#69603
On 11/6/2019 7:55 PM, Öö Tiib wrote:
> On Wednesday, 6 November 2019 19:16:08 UTC+2, Manfred  wrote:
>> On 11/6/2019 4:54 PM, Paavo Helde wrote:
>>> Seriously?
>>>
>>> std::string make_pathname(const std::string& dir,
>>>       const std::string& fname, const std::string& ext)
>>> {
>>>       return dir + "/" + fname + "." + ext;
>>> }
>>>
>>> No need to check for any overflows.
>>
>> How do you think that overflow check is done inside std::string?
> 
> All standard library writers are rather good programmers.
> Obviously they have something that is easy to read from afar that it does
> no way overflow. Likely it is some short inline member to call
> when size is supposed to grow that does the check:
> 
>      if (max_size() - size() < size_to_add)
>          throw std::length_error(text_to_throw);
> 
> Why don't you look into any of implementations in your computer?
> 

My reply was about the comment "No need to check for any overflows." - 
obviously if you do C++ programming you need to know how to check for 
integer overflow (and we all know how to use '+' with std::string, but 
we may also need to calculate e.g. a length of a std::vector to resize, 
and check for overflow in the process)

The fragment you posted obviously works well with no need for unsigned 
wrapping (I didn't say you can't do without, I said it's more efficient 
and less verbose if you have it), but it also has different requirements 
than the example I posted: two strings only, with the precondition that 
the 'this' string is less than max_size() long.

Just to stick with this example (although my point was about integer 
overflow rather than string concatenation), you see that if you lift 
these preconditions and need to concat more than 2 strings (as it was in 
the example) then either you precalculate the total length of the final 
string with a series of additions (and you see that the example is more 
efficient, more clear and less verbose than a series of if/else) or you 
do string+string+string and you end up with multiple allocations and 
copies (and yes, as often as this is totally irrelevant, sometimes this 
does matter).

This is to say that if you want to handle integer overflow efficiently, 
then unsigned wrapping /is/ useful, it is not a "major design mistake" - 
which is what triggered all this (for me at least).

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


#69612

FromPaavo Helde <myfirstname@osa.pri.ee>
Date2019-11-06 22:25 +0200
Message-ID<qpva7j$hlr$1@dont-email.me>
In reply to#69609
On 6.11.2019 21:53, Manfred wrote:
> Just to stick with this example (although my point was about integer
> overflow rather than string concatenation), you see that if you lift
> these preconditions and need to concat more than 2 strings (as it was in
> the example) then either you precalculate the total length of the final
> string with a series of additions (and you see that the example is more
> efficient, more clear and less verbose than a series of if/else) or you
> do string+string+string and you end up with multiple allocations and
> copies (and yes, as often as this is totally irrelevant, sometimes this
> does matter).

If the profiler shows the multiple allocations in this function are 
creating a bottleneck, you can avoid this easily:

std::string make_pathname(const std::string& dir,
      const std::string& fname, const std::string& ext)
{
      std::string result;
      result.reserve(dir.length()+fname.length()+ext.length()+2);
      result += dir;
      result += '/';
      result += fname;
      result += '.';
      result += ext;
      return result;
}

There is still no need to check for overflow.

Note that if there is an overflow, reserve() will reserve less memory 
than needed, but that's OK because the later += operations will check 
for it anyway.

And if a future C++ implementation makes unsigned wrapping undefined and 
the above addition overflows, triggers an assertion and terminates the 
program, then this would be a better result than trying to compose a 
filename which won't fit in memory.

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


#69616

FromManfred <noname@add.invalid>
Date2019-11-06 23:05 +0100
Message-ID<qpvg35$6tc$1@gioia.aioe.org>
In reply to#69612
On 11/6/2019 9:25 PM, Paavo Helde wrote:
> On 6.11.2019 21:53, Manfred wrote:
>> Just to stick with this example (although my point was about integer
>> overflow rather than string concatenation), you see that if you lift
>> these preconditions and need to concat more than 2 strings (as it was in
>> the example) then either you precalculate the total length of the final
>> string with a series of additions (and you see that the example is more
>> efficient, more clear and less verbose than a series of if/else) or you
>> do string+string+string and you end up with multiple allocations and
>> copies (and yes, as often as this is totally irrelevant, sometimes this
>> does matter).
> 
> If the profiler shows the multiple allocations in this function are 
> creating a bottleneck, you can avoid this easily:
> 
> std::string make_pathname(const std::string& dir,
>       const std::string& fname, const std::string& ext)
> {
>       std::string result;
>       result.reserve(dir.length()+fname.length()+ext.length()+2);
>       result += dir;
>       result += '/';
>       result += fname;
>       result += '.';
>       result += ext;
>       return result;
> }
> 
> There is still no need to check for overflow.
> 
> Note that if there is an overflow, reserve() will reserve less memory 
> than needed, but that's OK because the later += operations will check 
> for it anyway.
Note that here you are still assuming wrapping.

> 
> And if a future C++ implementation makes unsigned wrapping undefined
Undefined? Then I believe it wouldn't work.

  and
> the above addition overflows, triggers an assertion and terminates the 
> program, then this would be a better result than trying to compose a 
> filename which won't fit in memory.
> 
And here you are still assuming defined behavior (implying that every 
single integer operation is checked at runtime).
Moreover, program termination is /not/ safe coding - you know what DoS 
attack is.

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


#69621

FromPaavo Helde <myfirstname@osa.pri.ee>
Date2019-11-07 10:23 +0200
Message-ID<qq0k9d$pq1$1@dont-email.me>
In reply to#69616
On 7.11.2019 0:05, Manfred wrote:
> On 11/6/2019 9:25 PM, Paavo Helde wrote:
    and
>> the above addition overflows, triggers an assertion and terminates the
>> program, then this would be a better result than trying to compose a
>> filename which won't fit in memory.
>>
> And here you are still assuming defined behavior (implying that every
> single integer operation is checked at runtime).
> Moreover, program termination is /not/ safe coding - you know what DoS
> attack is.

Yes, one needs to protect against attacks. However, if somebody has 
managed to send in gigabytes or exabytes of path strings into my program 
the DoS attack has already happened, as storing and processing them will 
take a lot of resources.

I agree that one needs to check against overflows where appropriate, but 
this pathname concatenation example is about the silliest one could 
imagine. If you look at the original page 
"http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1969.htm" you see that 
this is not the part he is demonstrating or discussing (it's not colored 
in red like rsize_t additions). That's just some lines which he has 
copied over from the earlier "unsafe" sample without any changes. He 
does not argue that this is the best way to check for integer overflows, 
that's just some copy-paste lines which are short and do no harm.

Note that the whole page is about *buffer overflows*, not *integer 
overflows*.

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


#69614

FromDavid Brown <david.brown@hesbynett.no>
Date2019-11-06 22:20 +0100
Message-ID<qpvde4$5c9$1@dont-email.me>
In reply to#69609
On 06/11/2019 20:53, Manfred wrote:

> This is to say that if you want to handle integer overflow efficiently, 
> then unsigned wrapping /is/ useful, it is not a "major design mistake" - 
> which is what triggered all this (for me at least).

I partly agree on this (despite disagreeing about the example you gave). 
  Unsigned wrapping is one way to handle integer overflow efficiently. 
It is not the only way, and not necessarily the best way, but it can 
sometimes be useful.

One thing to note is that when the checks are handled within the 
standard library (such as for C++ string concatenation), the 
implementation does not need to stick to portable, standard C++.  A gcc 
standard library could use "#pragma GCC optimize(("fwrapv"))" and 
wrapping signed integer arithmetic, if it preferred.  Or it could use 
__int128 types, or the overflow __builtins - whatever gives the best 
results.

But if you are writing portable, standard C or C++ and need to check for 
overflows, unsigned wrapping is sometimes the best solution.

However, I would say that the main reason for having unsigned integers 
wrap is simply that sometimes you want wrapping behaviour - overflow 
detection is only one of a number of possible applications for wrapping.

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


#69611

FromPaavo Helde <myfirstname@osa.pri.ee>
Date2019-11-06 22:12 +0200
Message-ID<qpv9f2$cno$1@dont-email.me>
In reply to#69601
On 6.11.2019 19:15, Manfred wrote:
> On 11/6/2019 4:54 PM, Paavo Helde wrote:
>
>> std::string make_pathname(const std::string& dir,
>>      const std::string& fname, const std::string& ext)
>> {
>>      return dir + "/" + fname + "." + ext;
>> }
>>
>> No need to check for any overflows.
>
> How do you think that overflow check is done inside std::string?

I'm pretty confident it's done properly. Note that std::string would 
even be allowed to use implementation-specific features which are UB by 
the standard, should it be necessary.

>>
>> Not to speak about that there cannot be overflow in the first place
>> because if pathlen overflows the three strings dir, fname and ext
>> would not fit in the process memory anyway.
>>
>> Not to speak about that the time lost for a more explicit check for
>> overflow would be zero or unmeasurable, compared to any file access
>> itself, or even when compared to the malloc() call in the same function.
>>
>>
>
> What do you mean with "more explicit check for overflow"?
>
> Assuming you know the variables are 32-bit unsigned, I suppose you could do
> if (pathlen < 0xFFFFFFFF-filelen)
> {
>    pathlen += filelen;
> }
> else
> {
>    return 0;
> }

Yes, that's what I meant by "more explicit". And there is 
std::numeric_limits<T>::max(), no need for 0xFFFFFFFFF magic numbers.

>
> and then repeat, but honestly I don't see the benefit of it compared to
> the above (as a first you are introducing a dependency on the specific
> integer size).
> Or you can cast to a wider type, but then you are not solving the
> problem, you are only moving it forward, and still I wouldn't see the
> benefit.

To be honest, the check I would wrote would be something along to:

if (strlen(filename)>10000) {
	throw std::runtime_error("You must be kidding");
}

and it would happen way before any make_pathname() function.

>
> Besides, this is about /integer/ overflow check, so it could apply to
> more computations other than memory size.

No, the variables in your example were size_t.

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


#69679

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2019-11-09 06:24 -0800
Message-ID<86lfspcekw.fsf@linuxsc.com>
In reply to#69575
Paavo Helde <myfirstname@osa.pri.ee> writes:

> On 5.11.2019 17:58, Bonita Montero wrote:
>
>> With the same reasoning you could say that unsigneds might never
>> wrap;  but in fact they're specified to wrap.
>
> In retrospect, this (wrapping unsigneds) looks like a major design mistake.
>
> IMO, wrapping integers (signed or unsigned) are an example of
> "optimization which nobody asked for", and they are there basically
> only because the hardware happened to support such operations.

Apparently you think how the hardware behaves (specifically, for
unsigned or two's complement operands) is some sort of accident
of history.  It isn't.  It was a deliberate choice, made by smart
people.  It isn't just a coincidence that the semantics of
wrapping works nicely in a variety of applications.

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


#69683

FromSiri Cruise <chine.bleu@yahoo.com>
Date2019-11-09 07:14 -0700
Message-ID<chine.bleu-C27EF7.07143109112019@reader.eternal-september.org>
In reply to#69679
In article <86lfspcekw.fsf@linuxsc.com>,
 Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:

> Paavo Helde <myfirstname@osa.pri.ee> writes:
> 
> > On 5.11.2019 17:58, Bonita Montero wrote:
> >
> >> With the same reasoning you could say that unsigneds might never
> >> wrap;  but in fact they're specified to wrap.
> >
> > In retrospect, this (wrapping unsigneds) looks like a major design mistake.
> >
> > IMO, wrapping integers (signed or unsigned) are an example of
> > "optimization which nobody asked for", and they are there basically
> > only because the hardware happened to support such operations.
> 
> Apparently you think how the hardware behaves (specifically, for
> unsigned or two's complement operands) is some sort of accident
> of history.  It isn't.  It was a deliberate choice, made by smart
> people.  It isn't just a coincidence that the semantics of
> wrapping works nicely in a variety of applications.

CPUs with an overflow flag note additions that overflow the register. A compiler 
can implement integer overflow exceptions on such CPUs.

-- 
:-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted.    @
'I desire mercy, not sacrifice.'                                    /|\
The first law of discordiamism: The more energy   This post         / \
to make order is nore energy made into entropy.   insults Islam.  Mohammed

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


#69698

FromDavid Brown <david.brown@hesbynett.no>
Date2019-11-10 11:52 +0100
Message-ID<qq8q4n$n4c$1@dont-email.me>
In reply to#69679
On 09/11/2019 15:24, Tim Rentsch wrote:
> Paavo Helde <myfirstname@osa.pri.ee> writes:
> 
>> On 5.11.2019 17:58, Bonita Montero wrote:
>>
>>> With the same reasoning you could say that unsigneds might never
>>> wrap;  but in fact they're specified to wrap.
>>
>> In retrospect, this (wrapping unsigneds) looks like a major design mistake.
>>
>> IMO, wrapping integers (signed or unsigned) are an example of
>> "optimization which nobody asked for", and they are there basically
>> only because the hardware happened to support such operations.
> 
> Apparently you think how the hardware behaves (specifically, for
> unsigned or two's complement operands) is some sort of accident
> of history.  It isn't.  It was a deliberate choice, made by smart
> people.  It isn't just a coincidence that the semantics of
> wrapping works nicely in a variety of applications.
> 

Wrapping in hardware was not a deliberate choice of semantics - it was a 
deliberate choice of the simplest, fastest and most efficient hardware 
with little concern for the semantics.

There are three primary choices for defined behaviour of signed integer 
overflow - saturation, trapping, and wrapping.  None of these matches 
mathematical integer behaviour, of course.  Saturation is a natural and 
useful choice in many circumstances.  Trapping (including NaN 
implementations) is a good way of seeing that something has gone wrong, 
so that you either have the right answer, or know there has been an 
error.  Wrapping has no logical use or point as a semantic of an 
operation.  It is, however, a very convenient aid to multi-precision 
arithmetic.

Implementations of signed integer representations other than two's 
complement, such as ones' complement and sign-magnitude, do not 
typically have wrapping semantics - they will have trapping or 
saturation semantics, if they have defined semantics.

But in hardware, two's complement representation is the simplest and 
most efficient method.  And if you have wrapping for addition and 
subtraction, it becomes easily expandable - a vital feature from the 
days of 8-bit ALU's being used for 16-bit, 32-bit and larger arithmetic, 
and still useful occasionally.  This is related to the reason why in 
many cpu's, there is a "carry" flag for addition that doubles as the 
"not borrow" flag for subtraction - it means you implement your 
subtraction "x - y" as "x + ~y" and re-use almost all the hardware elements.

Saturation and trapping cost hardware - the wrapping is free.  It would 
be the standard in hardware even if it didn't have the use for 
multi-precision arithmetic.

Paavo is right when viewed from the high-level software perspective - 
wrapping is not something people looked for, either for signed or 
unsigned arithmetic.  For very low-level software, it /is/ useful in the 
case where you are building up larger arithmetic operations from smaller 
ones, and for certain kinds of comparisons - these are things that are 
mostly hidden by the compiler in a high level language like C.

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


#69701

FromPaavo Helde <myfirstname@osa.pri.ee>
Date2019-11-10 16:31 +0200
Message-ID<qq96vl$7iq$1@dont-email.me>
In reply to#69679
On 9.11.2019 16:24, Tim Rentsch wrote:
> Paavo Helde <myfirstname@osa.pri.ee> writes:
>
>> On 5.11.2019 17:58, Bonita Montero wrote:
>>
>>> With the same reasoning you could say that unsigneds might never
>>> wrap;  but in fact they're specified to wrap.
>>
>> In retrospect, this (wrapping unsigneds) looks like a major design mistake.
>>
>> IMO, wrapping integers (signed or unsigned) are an example of
>> "optimization which nobody asked for", and they are there basically
>> only because the hardware happened to support such operations.
>
> Apparently you think how the hardware behaves (specifically, for
> unsigned or two's complement operands) is some sort of accident
> of history.  It isn't.  It was a deliberate choice, made by smart
> people.  It isn't just a coincidence that the semantics of
> wrapping works nicely in a variety of applications.

The hardware which I am familiar with properly sets the carry and 
overflow flags for arithmetic operations. In case of multiplication it 
also produces the result twice larger than the operands, in order to not 
lose information. So at the hardware level the results are always 
well-defined and complete, this is very fine. The calling program can 
study the flags and decide what to do about this.

The problem with C is that they decided the best way to deal with this 
is just to ignore the overflow flag and the upper half of the 
multiplication result. Not sure about PDP-11 itself, but they had to 
think about other hardware too, and at some point they decided that the 
best way to deal with the problem was just to ignore all the extra 
information the current or future CPU-s might provide.

An imaginary conversation:

A: BTW, what should we do with the arithmetic overflow? There are 
overflow flags and extended precision results in some hardware that we 
could use.

B: Because of speed and simplicity, we just ignore it. Each extra opcode 
would slow us down!

A: But in case of multiplication, we might lose half of the result!

B. Just ignore it.

A. But what we write down in the specs? We can't just say we carry out 
an hardware operation and then ignore everything except the first result 
register.

B. Let's see... Isn't there a nice name for that behavior? Yep, it's 
called wrapping! Write this down in the specs!

A. But, but, with signed integers, there are different representations, 
so that on some hardware it does not actually wrap!

B. Ouch, my head is hurting. Just declare it undefined then!

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


#69706

FromManfred <noname@invalid.add>
Date2019-11-10 19:02 +0100
Message-ID<qq9jbb$gap$1@gioia.aioe.org>
In reply to#69701
On 11/10/19 3:31 PM, Paavo Helde wrote:
> On 9.11.2019 16:24, Tim Rentsch wrote:
>> Paavo Helde <myfirstname@osa.pri.ee> writes:
>>
>>> On 5.11.2019 17:58, Bonita Montero wrote:
>>>
>>>> With the same reasoning you could say that unsigneds might never
>>>> wrap;  but in fact they're specified to wrap.
>>>
>>> In retrospect, this (wrapping unsigneds) looks like a major design 
>>> mistake.
>>>
>>> IMO, wrapping integers (signed or unsigned) are an example of
>>> "optimization which nobody asked for", and they are there basically
>>> only because the hardware happened to support such operations.
>>
>> Apparently you think how the hardware behaves (specifically, for
>> unsigned or two's complement operands) is some sort of accident
>> of history.  It isn't.  It was a deliberate choice, made by smart
>> people.  It isn't just a coincidence that the semantics of
>> wrapping works nicely in a variety of applications.
> 
> The hardware which I am familiar with properly sets the carry and 
> overflow flags for arithmetic operations. In case of multiplication it 
> also produces the result twice larger than the operands, in order to not 
> lose information. So at the hardware level the results are always 
> well-defined and complete, this is very fine. The calling program can 
> study the flags and decide what to do about this.

The main difference between the hardware and the language is that 1) the 
former can count on accessory entities that are not part of a variable 
(the flags register) and 2) it does not have to fit within the semantics 
of a type system, so that it is OK for WORD op WORD to yield DWORD

If you go into the specifics, you may see that:
1) flags information would need to be handled by the compiler, with the 
possible result of littering the generated code with branches for every 
integer expression.

2) Having an arithmetic operator (multiplication) yield a different type 
than the operands would pose significant complications to the language - 
if you really want this, try mimicking that with some C++ wrapper 
classes and operators thereof, and see where you go.
The solution, when the full range is needed, is to tell the compiler 
that this is what you want by casting the /operands/.
In this way the compiler can deliver the result you want (while 
optimizing away the extra space for the operands themselves).

> 
> The problem with C is that they decided the best way to deal with this 
> is just to ignore the overflow flag and the upper half of the 
> multiplication result. Not sure about PDP-11 itself, but they had to 
> think about other hardware too, and at some point they decided that the 
> best way to deal with the problem was just to ignore all the extra 
> information the current or future CPU-s might provide

See above.
Moreover, given the impact of the choice, and its business consequences, 
it is hard to believe that this was just sloppiness.

> 
> An imaginary conversation:
> 
> A: BTW, what should we do with the arithmetic overflow? There are 
> overflow flags and extended precision results in some hardware that we 
> could use.
> 
> B: Because of speed and simplicity, we just ignore it. Each extra opcode 
> would slow us down!
> 
> A: But in case of multiplication, we might lose half of the result!
> 
> B. Just ignore it.
> 
> A. But what we write down in the specs? We can't just say we carry out 
> an hardware operation and then ignore everything except the first result 
> register.
> 
> B. Let's see... Isn't there a nice name for that behavior? Yep, it's 
> called wrapping! Write this down in the specs!
> 
> A. But, but, with signed integers, there are different representations, 
> so that on some hardware it does not actually wrap!
> 
> B. Ouch, my head is hurting. Just declare it undefined then!
> 
> 

This is fiction.

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


#69709

FromPaavo Helde <myfirstname@osa.pri.ee>
Date2019-11-11 12:08 +0200
Message-ID<qqbbvo$fce$1@dont-email.me>
In reply to#69706
On 10.11.2019 20:02, Manfred wrote:
> The main difference between the hardware and the language is that 1) the
> former can count on accessory entities that are not part of a variable
> (the flags register) and 2) it does not have to fit within the semantics
> of a type system, so that it is OK for WORD op WORD to yield DWORD
>
> If you go into the specifics, you may see that:
> 1) flags information would need to be handled by the compiler, with the
> possible result of littering the generated code with branches for every
> integer expression.

Yes, that's correct.

> 2) Having an arithmetic operator (multiplication) yield a different type
> than the operands would pose significant complications to the language -
> if you really want this, try mimicking that with some C++ wrapper
> classes and operators thereof, and see where you go.
> The solution, when the full range is needed, is to tell the compiler
> that this is what you want by casting the /operands/.
> In this way the compiler can deliver the result you want (while
> optimizing away the extra space for the operands themselves).

Note that when the operands are cast to suitable larger types, then 
overflow cannot happen, so for this usage case the overflow behavior 
does not need to be defined.

>
>>
>> The problem with C is that they decided the best way to deal with this
>> is just to ignore the overflow flag and the upper half of the
>> multiplication result. Not sure about PDP-11 itself, but they had to
>> think about other hardware too, and at some point they decided that
>> the best way to deal with the problem was just to ignore all the extra
>> information the current or future CPU-s might provide
>
> See above.
> Moreover, given the impact of the choice, and its business consequences,
> it is hard to believe that this was just sloppiness.

Of course not. The decision to produce fastest code was a deliberate 
choice made by smart people, as you said. Any kind of overflow checking 
would have slowed the code down at least twice, which would have been of 
course disastrous for a language meant as "better assembler".

With the specified wrapping behavior for unsigneds the story is 
different however. They defined the unsigned overflow as wrapping 
because they could, not because of some deeper considerations. Would the 
existing hardware have provided some other behavior (like saturating) at 
zero cost, I'm sure they would have standardized that behavior instead.

Note that they did not just copy the hardware behavior. The common 
hardware itself does not have wrapping behavior, rather it produces the 
correct result with carry/overflow flags and extended registers. One 
only gets wrapping behavior by deliberately ignoring the correct result.

In a similar token, they did not define the behavior for signed overflow 
because they couldn't. More specifically, the zero cost behavior was 
different on different hardware, and they could not find enough 
justification for any kind of non-zero cost overflow behavior.

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


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

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


csiph-web