Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #69548 > unrolled thread
| Started by | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| First post | 2019-11-04 20:48 +0100 |
| Last post | 2020-02-26 02:22 +0000 |
| Articles | 20 on this page of 219 — 25 participants |
Back to article view | Back to comp.lang.c++
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 4 of 11 — ← Prev page 1 2 3 [4] 5 6 … 11 Next page →
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-11-05 23:14 +0100 |
| Message-ID | <qpss93$3ee$1@dont-email.me> |
| In reply to | #69574 |
On 05/11/2019 19:31, Manfred wrote: > On 11/5/19 6:02 PM, Öö Tiib wrote: >> On Tuesday, 5 November 2019 11:31:39 UTC+2, David Brown wrote: >>> >>> When people can't agree, and when every option has its advantages and >>> disadvantages, the only rational solution is to give people an explicit >>> choice. > > Except when giving a choice complicates the matter more than the > benefits it can give. > From this perspective I like compiler flags more than adding new source > code constructs. Maybe because I think that signed wrapping, unlike > unsigned, is of no practical use. > Personally, I think signed wrapping is only useful very occasionally - and unsigned wrapping only slightly more often. But when you need wrapping, it is a lot more efficient to have it than to have to mess around with checks for overflows. I don't like compiler flags as a solution here, because it is disconnected from the code. (Though flags are excellent for when you have to work with code written by someone who doesn't understand the language and has only tested with inferior compilers.) If I have code that makes use of additional semantics, like wrapping integers or invalid pointer casts, I put the flags in the code as pragmas (or gcc function attributes). That way the code will work regardless of the flags used to compile the code. It also gives a fine place to put comments explaining the issue. >> >> There are lot of aspects that majority of people involved seem to >> agree with. > > I, for one, find some of them questionable. > >> >> * on majority of cases overflow (even unsigned) is programming error > That's my first - unsigned wrapping /can/ be useful in some contexts. I > can't say if it is about the majority of cases, but it is enough to keep > it in place. > I think it can be agreed that sometimes the wrapping is useful, and sometimes it is a programming error. But people disagree about the split, both for signed and unsigned types. > >> * efficiency is of low importance for lot of code > Disagree. It is not always important, but it is important enough to be > one of the main reasons to choose C++, so it should be of primary > importance for the language. There are many good reasons for choosing C++ other than efficiency. It is a well-established fact that in almost all code, only small sections are performance critical. That does not mean we want intentionally inefficient code in the rest of it, of course. And if the code gets full of run-time checks then it /would/ end up as inefficient.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-11-05 23:00 +0100 |
| Message-ID | <qpsrd4$tr3$1@dont-email.me> |
| In reply to | #69571 |
On 05/11/2019 18:02, Öö Tiib wrote: > On Tuesday, 5 November 2019 11:31:39 UTC+2, David Brown wrote: >> >> When people can't agree, and when every option has its advantages and >> disadvantages, the only rational solution is to give people an explicit >> choice. > > There are lot of aspects that majority of people involved seem to > agree with. > > * on majority of cases overflow (even unsigned) is programming error Agreed. > * trap (overflow that signals or throws) helps to find programming > errors most reliably and quickly Agreed (where "trap" could mean any kind of notification, exception, error log, etc.). But this is something you might only want during debugging - it is of significant efficiency cost. > * wrap (overflow with modular arithmetic) can be used intentionally > and efficiently in some algorithms It is occasionally, but rarely, useful. > * snap (overflow that results with saturating nan) is good when > damaged, disconnected or short circuited (temperature?) sensor > should not turn our device (airplane?) into brick Saturation in general can be useful. > * compiler assuming that overflow not occurring is ensured by some > external logic may allow noteworthy optimizations Agreed. > * efficiency is of low importance for lot of code Agreed. > * efficiency of C++ is one of its design goals Agreed. > * it is good when programmer's intention can be indicated in code Agreed. A couple of other options that I didn't mention before for overflows are: * NaN (signalling or quiet), so that you can do long calculations and then check at the end if it worked. * Unspecified value - the overflow will give a valid int (or whatever type is in use) value, but the compiler gives no information about what the value might be. This can be useful when you can detect something has failed, and return (valid, value) pairs. It will allow the compiler to take shortcuts and simplify calculations but not allow undefined behaviour to "move" forwards or backwards. > > So if to think of it then it is large puzzle indeed how to resolve it > elegantly and it continues to be bad to leave it all up to > implementations to decide and then each developer to struggle > with it on his own with "this standard imposes no requirements". > > I myself would like most current operators to trap on overflow > (by raising SIGFPE or throwing std::overflow_error) both for > signed and unsigned. I like that in debugging or finding problems - with tools like sanitizers. But I would not want that in normal code. With this kind of semantics, the compiler can't even simplify "x + 1 - 1" to "x". I much prefer to be able to write code in whatever way is simplest, clearest or most maintainable for /me/, knowing that the compiler will turn it into the most efficient results. I intentionally use an optimising compiler for C and C++ programming - when efficiency doesn't matter, I'll program in Python where integers grow to avoid overflow. > For wrap, snap and "compiler may assume that the operation > does not overflow" cases I would like new operators. > I suggested new types for the different behaviour, but of course it is the operations that have the behaviour, not the types. However, I can't see a convenient way to specify overflow behaviour on operations - using types is the best balance between flexibility and legible code.
[toc] | [prev] | [next] | [standalone]
| From | Öö Tiib <ootiib@hot.ee> |
|---|---|
| Date | 2019-11-06 05:26 -0800 |
| Message-ID | <d1487f24-9fad-4a77-8b11-9266200e733d@googlegroups.com> |
| In reply to | #69579 |
On Wednesday, 6 November 2019 00:00:16 UTC+2, David Brown wrote: > On 05/11/2019 18:02, Öö Tiib wrote: > > > * trap (overflow that signals or throws) helps to find programming > > errors most reliably and quickly > > Agreed (where "trap" could mean any kind of notification, exception, > error log, etc.). But this is something you might only want during > debugging - it is of significant efficiency cost. Indeed, majority of programming errors should be found during debugging. > > I myself would like most current operators to trap on overflow > > (by raising SIGFPE or throwing std::overflow_error) both for > > signed and unsigned. > > I like that in debugging or finding problems - with tools like > sanitizers. But I would not want that in normal code. With this kind > of semantics, the compiler can't even simplify "x + 1 - 1" to "x". It may be can or may be can not that depends on wording. I have not really thought it thru how to word the semantics precisely. The major purpose is to get errors when program is actually storing value into type where it does not fit (IOW really overflows). Analogical argument is that automatic storage overflow may not be trapped in principle since that would disallow optimizing recursions (that exhaust stack) into loops (that don't exhaust stack). The rules can be still likely worded in a way that implementation is allowed not to trap when it manages to get the job done without exhausting automatic storage somehow. > I much prefer to be able to write code in whatever way is simplest, > clearest or most maintainable for /me/, knowing that the compiler will > turn it into the most efficient results. I intentionally use an > optimising compiler for C and C++ programming - when efficiency doesn't > matter, I'll program in Python where integers grow to avoid overflow. I do almost same but I think of some of it slightly differently. Exact formula in programming is unfortunately more important than its clarity and intuitivity for reader. For example we need to calculate average of two values of A and B. Mathematically there are lot of ways to calculate it and what is most intuitive may depend on meaning of A and B. Like: 1) (A + B) / 2 2) A / 2 + B / 2 3) A + (B - A) / 2 4) B + (A - B) / 2 etc. But in software these can be very different expressions because these have different potential overflows and/or losses of accuracy. Until something helps to reduce that issue it is all about exactly that formula and period. As of efficiency It is anyway often uncertain until it is shown where the bottlenecks are. Also it can be often only shown by profiling products with realistic worst case loads of data and then it is usually small subset of code that can change overall efficiency. Python I use less not because of its bad performance but because I have failed to use it scalably. Lot of of lIttle script programs is great, but when any of those starts to grow bigger then my productivity with those drops. For C++ same feels like nonsensically unimportant size. Somehow in C++ I have learned to separate different concerns and to abstract details away but not in Python. > > For wrap, snap and "compiler may assume that the operation > > does not overflow" cases I would like new operators. > > > > I suggested new types for the different behaviour, but of course it is > the operations that have the behaviour, not the types. However, I can't > see a convenient way to specify overflow behaviour on operations - using > types is the best balance between flexibility and legible code. I mean totally new "advanced" operators like (A +% B) or (C +^ D). Yes there will be precedence (and may be associativity etc.) to define but it is business as usual and not some show-stopper issue. In some languages (like Swift) it is done and it seems to work fine.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-11-06 21:50 +0100 |
| Message-ID | <qpvbmb$qkk$1@dont-email.me> |
| In reply to | #69592 |
On 06/11/2019 14:26, Öö Tiib wrote: > On Wednesday, 6 November 2019 00:00:16 UTC+2, David Brown wrote: >> On 05/11/2019 18:02, Öö Tiib wrote: >> >>> * trap (overflow that signals or throws) helps to find programming >>> errors most reliably and quickly >> >> Agreed (where "trap" could mean any kind of notification, exception, >> error log, etc.). But this is something you might only want during >> debugging - it is of significant efficiency cost. > > Indeed, majority of programming errors should be found during > debugging. > >>> I myself would like most current operators to trap on overflow >>> (by raising SIGFPE or throwing std::overflow_error) both for >>> signed and unsigned. >> >> I like that in debugging or finding problems - with tools like >> sanitizers. But I would not want that in normal code. With this kind >> of semantics, the compiler can't even simplify "x + 1 - 1" to "x". > > It may be can or may be can not that depends on wording. > I have not really thought it thru how to word the semantics > precisely. The major purpose is to get errors when program > is actually storing value into type where it does not fit (IOW > really overflows). It is possible to consider intermediary results as "infinite precision", which would give you that optimisation. But how would you treat: x = x + 1; x = x - 1; Would that cause a trap if x started at 0x3ffffff (assuming 32-bit int)? What if "x" is held in a register rather than stored in memory? There are lots of possible inconsistencies here. (If it is any guide, gcc with "-ftrapv" optimises the two statements into "x". With "-fsanitize=signed-integer-overflow", the single expression "x + 1 - 1" is simplified to "x", but the two statements lead to checks.) Actually, it is worth looking at some gcc (or clang) generated code with -ftrapv and -fsanitize=signed-integer-overflow, perhaps with <https://gotbolt.org>, to see just host costly trapping semantics can be. They are very far from negligible. > > Analogical argument is that automatic storage overflow may > not be trapped in principle since that would disallow optimizing > recursions (that exhaust stack) into loops (that don't exhaust > stack). The rules can be still likely worded in a way that > implementation is allowed not to trap when it manages to get > the job done without exhausting automatic storage somehow. > >> I much prefer to be able to write code in whatever way is simplest, >> clearest or most maintainable for /me/, knowing that the compiler will >> turn it into the most efficient results. I intentionally use an >> optimising compiler for C and C++ programming - when efficiency doesn't >> matter, I'll program in Python where integers grow to avoid overflow. > > I do almost same but I think of some of it slightly differently. > Exact formula in programming is unfortunately more important > than its clarity and intuitivity for reader. > > For example we need to calculate average of two values of A and B. > Mathematically there are lot of ways to calculate it and what is > most intuitive may depend on meaning of A and B. Like: > 1) (A + B) / 2 > 2) A / 2 + B / 2 > 3) A + (B - A) / 2 > 4) B + (A - B) / 2 > etc. > But in software these can be very different expressions because > these have different potential overflows and/or losses of > accuracy. Until something helps to reduce that issue it is > all about exactly that formula and period. Yes. It is up to the programmer to ensure the expression is written in a way that does not overflow or lose accuracy (at least, not more than you are willing to lose). It is up to the compiler to pick the most efficient way to get the results requested from that expression, according to the rules of the language (and compiler flags) that determine the semantics of the expression. > > As of efficiency It is anyway often uncertain until it is > shown where the bottlenecks are. Also it can be often only > shown by profiling products with realistic worst case loads > of data and then it is usually small subset of code that can > change overall efficiency. > > Python I use less not because of its bad performance but > because I have failed to use it scalably. Lot of of lIttle script > programs is great, but when any of those starts to grow bigger > then my productivity with those drops. For C++ same feels like > nonsensically unimportant size. Somehow in C++ I have > learned to separate different concerns and to abstract details > away but not in Python. That's fine. Different languages have their advantages and disadvantages - and programmer preference is very subjective. > >>> For wrap, snap and "compiler may assume that the operation >>> does not overflow" cases I would like new operators. >>> >> >> I suggested new types for the different behaviour, but of course it is >> the operations that have the behaviour, not the types. However, I can't >> see a convenient way to specify overflow behaviour on operations - using >> types is the best balance between flexibility and legible code. > > I mean totally new "advanced" operators like (A +% B) or (C +^ D). > Yes there will be precedence (and may be associativity etc.) > to define but it is business as usual and not some show-stopper > issue. In some languages (like Swift) it is done and it seems to > work fine. > Ah, okay. I think there is a big risk of confusion here, and for people to forget which operators do what. (There is also the risk of accidentally writing smilies in your code!). I am happier with the type-based solution, and simply refusing to compile combinations of types that don't make sense (like adding a wrapping type and a saturation type). Undefined or unspecified behaviour types can be silently promoted to other more defined behaviour as needed. That also has the advantage that it can be done today, with current C++.
[toc] | [prev] | [next] | [standalone]
| From | Öö Tiib <ootiib@hot.ee> |
|---|---|
| Date | 2019-11-08 02:01 -0800 |
| Message-ID | <2105cdc6-bdd7-4908-9461-b7ffe1383cc1@googlegroups.com> |
| In reply to | #69613 |
On Wednesday, 6 November 2019 22:50:30 UTC+2, David Brown wrote: > On 06/11/2019 14:26, Öö Tiib wrote: > > On Wednesday, 6 November 2019 00:00:16 UTC+2, David Brown wrote: > >> On 05/11/2019 18:02, Öö Tiib wrote: > >> > >>> * trap (overflow that signals or throws) helps to find programming > >>> errors most reliably and quickly > >> > >> Agreed (where "trap" could mean any kind of notification, exception, > >> error log, etc.). But this is something you might only want during > >> debugging - it is of significant efficiency cost. > > > > Indeed, majority of programming errors should be found during > > debugging. > > > >>> I myself would like most current operators to trap on overflow > >>> (by raising SIGFPE or throwing std::overflow_error) both for > >>> signed and unsigned. > >> > >> I like that in debugging or finding problems - with tools like > >> sanitizers. But I would not want that in normal code. With this kind > >> of semantics, the compiler can't even simplify "x + 1 - 1" to "x". > > > > It may be can or may be can not that depends on wording. > > I have not really thought it thru how to word the semantics > > precisely. The major purpose is to get errors when program > > is actually storing value into type where it does not fit (IOW > > really overflows). > > It is possible to consider intermediary results as "infinite precision", > which would give you that optimisation. But how would you treat: > > x = x + 1; > x = x - 1; > > Would that cause a trap if x started at 0x3ffffff (assuming 32-bit int)? > What if "x" is held in a register rather than stored in memory? There > are lots of possible inconsistencies here. (If it is any guide, gcc > with "-ftrapv" optimises the two statements into "x". With > "-fsanitize=signed-integer-overflow", the single expression "x + 1 - 1" > is simplified to "x", but the two statements lead to checks.) Is it all very similar to issue like where compiler uses 80 bit long double (as best supported by hardware) to do mid-way double arithmetics and so the end result does not saturate into INF or -INF on that platform but it does on other that uses 64 bit double all the way. I feel dealing with such issue" to be *lot* easier than dealing with utter undefined behavior (that all such examples are by current scripture). For me every solution is better than undefined behavior. > Actually, it is worth looking at some gcc (or clang) generated code with > -ftrapv and -fsanitize=signed-integer-overflow, perhaps with > <https://gotbolt.org>, to see just host costly trapping semantics can > be. They are very far from negligible. I have looked and measured its actual impact quite a lot. My thinking of it (is surely biased but it) revolves around handful of points. 1) It is about default behavior, in most code its efficiency does not matter and for where it matters there indeed *must* be alternatives. 2) Efficiency of sub-steps of processing usually does matter where we intensively process lot of different data. With lot of data we do hit memory latency. Processing has been for decades so much cheaper that it can be worth to reduce memory latency problems by adding even more processing. For example 1:4 uncompressing is faster than copy. Note: it is ultra rare case where speed of memcpy is our actual bottleneck and not stupidity of copying same data over and over too lot or even copying it at all. Same is with processing same thing pointlessly over and over. 3) World evolves. The Swift, Rust, Go, and D communities already ask for hardware support for trapping integer conversions and trapping arithmetic. People like the languages. If hardware starts to support it better then C++ will seem backwards without convenient ways to use trapping integers in production code. 4) Compilers will evolve. What happened to "register" or "inline"? Same can happen with usage of current "assume that it does not overflow" operations. Just make those not default but performance optimizations like register and inline. > >>> For wrap, snap and "compiler may assume that the operation > >>> does not overflow" cases I would like new operators. > >>> > >> > >> I suggested new types for the different behaviour, but of course it is > >> the operations that have the behaviour, not the types. However, I can't > >> see a convenient way to specify overflow behaviour on operations - using > >> types is the best balance between flexibility and legible code. > > > > I mean totally new "advanced" operators like (A +% B) or (C +^ D). > > Yes there will be precedence (and may be associativity etc.) > > to define but it is business as usual and not some show-stopper > > issue. In some languages (like Swift) it is done and it seems to > > work fine. > > > > Ah, okay. I think there is a big risk of confusion here, and for people > to forget which operators do what. (There is also the risk of > accidentally writing smilies in your code!). It is not that. We see wrapping and saturating is used rarely. Also wrapping is on half of cases used without need where it can confuse like "for (unsigned u = 10; u < 11; --u)". There will not be lot of mixed usages, just sometimes. > I am happier with the type-based solution, and simply refusing to > compile combinations of types that don't make sense (like adding a > wrapping type and a saturation type). Undefined or unspecified > behaviour types can be silently promoted to other more defined behaviour > as needed. That saturating type perhaps has to be separate type indeed. It will have "magical" values and so needs separate protection. On rest of cases operators feel to be best. About too implicit conversions ... it is another source of hard-to-notice defects. > That also has the advantage that it can be done today, with current C++. Life has shown that library features (or even worse "debugging tools") as opposed to language features will be adopted slowly by programmers and the compiler writers are even slower to start thinking in correct direction.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-11-08 14:03 +0100 |
| Message-ID | <qq3p39$f7g$1@dont-email.me> |
| In reply to | #69651 |
On 08/11/2019 11:01, Öö Tiib wrote: > On Wednesday, 6 November 2019 22:50:30 UTC+2, David Brown wrote: >> On 06/11/2019 14:26, Öö Tiib wrote: >>> On Wednesday, 6 November 2019 00:00:16 UTC+2, David Brown wrote: >>>> On 05/11/2019 18:02, Öö Tiib wrote: >>>> >>>>> * trap (overflow that signals or throws) helps to find programming >>>>> errors most reliably and quickly >>>> >>>> Agreed (where "trap" could mean any kind of notification, exception, >>>> error log, etc.). But this is something you might only want during >>>> debugging - it is of significant efficiency cost. >>> >>> Indeed, majority of programming errors should be found during >>> debugging. >>> >>>>> I myself would like most current operators to trap on overflow >>>>> (by raising SIGFPE or throwing std::overflow_error) both for >>>>> signed and unsigned. >>>> >>>> I like that in debugging or finding problems - with tools like >>>> sanitizers. But I would not want that in normal code. With this kind >>>> of semantics, the compiler can't even simplify "x + 1 - 1" to "x". >>> >>> It may be can or may be can not that depends on wording. >>> I have not really thought it thru how to word the semantics >>> precisely. The major purpose is to get errors when program >>> is actually storing value into type where it does not fit (IOW >>> really overflows). >> >> It is possible to consider intermediary results as "infinite precision", >> which would give you that optimisation. But how would you treat: >> >> x = x + 1; >> x = x - 1; >> >> Would that cause a trap if x started at 0x3ffffff (assuming 32-bit int)? >> What if "x" is held in a register rather than stored in memory? There >> are lots of possible inconsistencies here. (If it is any guide, gcc >> with "-ftrapv" optimises the two statements into "x". With >> "-fsanitize=signed-integer-overflow", the single expression "x + 1 - 1" >> is simplified to "x", but the two statements lead to checks.) > > Is it all very similar to issue like where compiler uses 80 bit > long double (as best supported by hardware) to do mid-way > double arithmetics and so the end result does not saturate into > INF or -INF on that platform but it does on other that uses > 64 bit double all the way. > Yes - and that is a real mess for standardisation and repeatability. It's okay if you are not bothered about the portability and repeatability of your floating point calculations, and are happy to accept that an unrelated change in one part of your program can lead to different results somewhere else just because it changed when floating point registers get moved out into the stack. If that's fine, you can use "-ffast-math" or equivalent switches and tell your compiler it is free to make such code. (Personally, I use "-ffast-math" in my own code - but it is not something everyone wants.) I do not want that situation in integer code. I fully expect the compiler to generate identical code - equally efficient, equal results, equal levels of static checking - whether I break a calculation into multiple statements or have it all as one expression. I want to make the decisions about the arrangements based on the clarity of the code, not on where I want the compiler to optimise or where I want it to insert hidden range checks. I am much happier with the function of "-fsanitize=signed-integer-overflow" here - it generates more checks, less efficient code, but the functionality is clear and consistent. I'll use that when I am happy to take the performance hit in the name of debugging code. > I feel dealing with such issue" to be *lot* easier than dealing > with utter undefined behavior (that all such examples are by > current scripture). For me every solution is better than > undefined behavior. The whole point is that you /don't/ hit undefined behaviour. Any time your code attempts to execute something with undefined behaviour, it is a bug in your code. Tools (like sanitizers) that help you find the undefined behaviour are good. Static analysis can help too. Once you have your code correct, you are not doing anything undefined, and there is no need for run-time checks that can't ever be triggered. To me, undefined behaviour is /better/ than the alternatives for most purposes. It helps me write better and more correct code, and as a bonus it is more efficient. Maybe this is something that stems from my programming education - I was taught in terms of specifications. Any function has a specification that gives its pre-conditions and its post-conditions. The function will assume the pre-conditions are valid, and establish the post-conditions. If you don't ensure you satisfy the pre-conditions before calling the function, you have no write to expect any know behaviour at all from the function. This principle is known popularly as "garbage in, garbage out". It has been understood since the birth of the programmable computer: """ On two occasions I have been asked, 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question. """ If you want to say that some programmers don't know that integer overflow is undefined behaviour, and think it wraps, then blame the way C and C++ is taught and what the books say, and do something about that - don't try to dumb down and water out the language. > >> Actually, it is worth looking at some gcc (or clang) generated code with >> -ftrapv and -fsanitize=signed-integer-overflow, perhaps with >> <https://gotbolt.org>, to see just host costly trapping semantics can >> be. They are very far from negligible. > > I have looked and measured its actual impact quite a lot. My > thinking of it (is surely biased but it) revolves around handful of > points. > > 1) It is about default behavior, in most code its efficiency does > not matter and for where it matters there indeed *must* be > alternatives. C++ (and C) are often chosen because of their efficiency. If you start adding run-time tests everywhere, you lose that. Why would you then use C and C++ at all? If you want extra safety and are willing to pay the efficiency price, there are other languages to choose from - such as Java or C#. When you choose to program in C or C++, you are accepting a responsibility to program carefully and correctly. You are picking a language that trusts the programmer. Why would you then want the language or compiler to tell you "I /know/ you claim to be a good programmer who knows the language and codes carefully - but I don't believe you, and I'm going to nanny you all the way" ? And once you start saying "C++ programmers can't be trusted to write expressions that don't overflow", where do you stop? Can you trust them to use pointers, or do you want run-time checks on all uses of pointers? Can you trust them to use arrays? Function pointers? Memory allocation? Multi-threading? There are many, many causes of faults and bugs in C++ programs that are going to turn up a lot more often than integer overflows (at least in the 32-bit world - most calculations don't come close to that limit). > > 2) Efficiency of sub-steps of processing usually does matter > where we intensively process lot of different data. With lot of data > we do hit memory latency. Processing has been for decades so > much cheaper that it can be worth to reduce memory latency > problems by adding even more processing. For example 1:4 > uncompressing is faster than copy. > Note: it is ultra rare case where speed of memcpy is our actual > bottleneck and not stupidity of copying same data over and > over too lot or even copying it at all. Same is with processing > same thing pointlessly over and over. > > 3) World evolves. The Swift, Rust, Go, and D communities > already ask for hardware support for trapping integer > conversions and trapping arithmetic. People like the languages. > If hardware starts to support it better then C++ will seem > backwards without convenient ways to use trapping integers > in production code. I have nothing against using trapping integer arithmetic in cases where it is useful. But it should only be as an active choice - either by choosing special types in the code, or by enabling debug options in the tools. And hardware-assisted trapping cannot reach the efficiency of having overflow as undefined behaviour, or even of wrapping, precisely for the reasons I gave above about optimising "x + 1 - 1". > > 4) Compilers will evolve. What happened to "register" or > "inline"? Same can happen with usage of current "assume > that it does not overflow" operations. Just make those not > default but performance optimizations like register and > inline. > >>>>> For wrap, snap and "compiler may assume that the operation >>>>> does not overflow" cases I would like new operators. >>>>> >>>> >>>> I suggested new types for the different behaviour, but of course it is >>>> the operations that have the behaviour, not the types. However, I can't >>>> see a convenient way to specify overflow behaviour on operations - using >>>> types is the best balance between flexibility and legible code. >>> >>> I mean totally new "advanced" operators like (A +% B) or (C +^ D). >>> Yes there will be precedence (and may be associativity etc.) >>> to define but it is business as usual and not some show-stopper >>> issue. In some languages (like Swift) it is done and it seems to >>> work fine. >>> >> >> Ah, okay. I think there is a big risk of confusion here, and for people >> to forget which operators do what. (There is also the risk of >> accidentally writing smilies in your code!). > > It is not that. We see wrapping and saturating is used rarely. And thus it should be written explicitly, with types that have names. Symbol combinations are easily mixed up and forgotten, especially if they are rarely used. One option - which could easily be implemented in C++ of today - would be to write "x + wrapping + y" as a wrapping addition operator. > Also wrapping is on half of cases used without need where > it can confuse like "for (unsigned u = 10; u < 11; --u)". That is an example of well-defined behaviour that is void of meaning. > There will not be lot of mixed usages, just sometimes. > >> I am happier with the type-based solution, and simply refusing to >> compile combinations of types that don't make sense (like adding a >> wrapping type and a saturation type). Undefined or unspecified >> behaviour types can be silently promoted to other more defined behaviour >> as needed. > > That saturating type perhaps has to be separate type indeed. It > will have "magical" values and so needs separate protection. > On rest of cases operators feel to be best. About too implicit > conversions ... it is another source of hard-to-notice defects. > I would be careful about providing implicit conversions. >> That also has the advantage that it can be done today, with current C++. > > Life has shown that library features (or even worse "debugging tools") > as opposed to language features will be adopted slowly by programmers > and the compiler writers are even slower to start thinking in correct > direction. > Life has shown that library features are precisely how C++ has evolved in the last decade or two - language features have mostly been added in order to make library features safer to use, easier to use, more efficient, or easier to implement. The next big leap for the C++ language - metaclasses - is precisely so that we can write libraries that handle things that would previously need language changes.
[toc] | [prev] | [next] | [standalone]
| From | Öö Tiib <ootiib@hot.ee> |
|---|---|
| Date | 2019-11-08 12:08 -0800 |
| Message-ID | <9bec0170-dcbe-4ec3-8c4f-c3bec03e865e@googlegroups.com> |
| In reply to | #69652 |
On Friday, 8 November 2019 15:03:54 UTC+2, David Brown wrote: > On 08/11/2019 11:01, Öö Tiib wrote: > > On Wednesday, 6 November 2019 22:50:30 UTC+2, David Brown wrote: > >> On 06/11/2019 14:26, Öö Tiib wrote: > >>> On Wednesday, 6 November 2019 00:00:16 UTC+2, David Brown wrote: > >>>> On 05/11/2019 18:02, Öö Tiib wrote: > >>>> > >>>>> * trap (overflow that signals or throws) helps to find programming > >>>>> errors most reliably and quickly > >>>> > >>>> Agreed (where "trap" could mean any kind of notification, exception, > >>>> error log, etc.). But this is something you might only want during > >>>> debugging - it is of significant efficiency cost. > >>> > >>> Indeed, majority of programming errors should be found during > >>> debugging. > >>> > >>>>> I myself would like most current operators to trap on overflow > >>>>> (by raising SIGFPE or throwing std::overflow_error) both for > >>>>> signed and unsigned. > >>>> > >>>> I like that in debugging or finding problems - with tools like > >>>> sanitizers. But I would not want that in normal code. With this kind > >>>> of semantics, the compiler can't even simplify "x + 1 - 1" to "x". > >>> > >>> It may be can or may be can not that depends on wording. > >>> I have not really thought it thru how to word the semantics > >>> precisely. The major purpose is to get errors when program > >>> is actually storing value into type where it does not fit (IOW > >>> really overflows). > >> > >> It is possible to consider intermediary results as "infinite precision", > >> which would give you that optimisation. But how would you treat: > >> > >> x = x + 1; > >> x = x - 1; > >> > >> Would that cause a trap if x started at 0x3ffffff (assuming 32-bit int)? > >> What if "x" is held in a register rather than stored in memory? There > >> are lots of possible inconsistencies here. (If it is any guide, gcc > >> with "-ftrapv" optimises the two statements into "x". With > >> "-fsanitize=signed-integer-overflow", the single expression "x + 1 - 1" > >> is simplified to "x", but the two statements lead to checks.) > > > > Is it all very similar to issue like where compiler uses 80 bit > > long double (as best supported by hardware) to do mid-way > > double arithmetics and so the end result does not saturate into > > INF or -INF on that platform but it does on other that uses > > 64 bit double all the way. > > > > Yes - and that is a real mess for standardisation and repeatability. > It's okay if you are not bothered about the portability and > repeatability of your floating point calculations, and are happy to > accept that an unrelated change in one part of your program can lead to > different results somewhere else just because it changed when floating > point registers get moved out into the stack. If that's fine, you can > use "-ffast-math" or equivalent switches and tell your compiler it is > free to make such code. (Personally, I use "-ffast-math" in my own code > - but it is not something everyone wants.) Yes, and for me it is fine if standard requires "x + 1 - 1" to trap if x + 1 does overflow. Compilers will add their fast math options in eye-blink anyway. > I do not want that situation in integer code. Then there won't be. > I am much happier with the function of > "-fsanitize=signed-integer-overflow" here - it generates more checks, > less efficient code, but the functionality is clear and consistent. > I'll use that when I am happy to take the performance hit in the name of > debugging code. It is not trapping math there but debugging tool that caught "undefined behavior". It does not help me on cases when I need trapping maths. > > > I feel dealing with such issue" to be *lot* easier than dealing > > with utter undefined behavior (that all such examples are by > > current scripture). For me every solution is better than > > undefined behavior. > > The whole point is that you /don't/ hit undefined behaviour. The whole issue that you seemingly don't understand is that there are cases (and those seem to be majority) where I don't need to have undefined behaviors nor wrapping behaviors nor arbitrarily growing precisions. I want it to trap by default and sometimes to have snapping behavior. But I have either undefined behavior with signed or wrapping behavior with unsigned and non-portable intrinsic functions. So I have to choose what hack is uglier to write trapping or snapping myself manually and everyone else in same situation like me has to do same. > To me, undefined behaviour is /better/ than the alternatives for most > purposes. It helps me write better and more correct code, and as a > bonus it is more efficient. It is better only when I know that it can no way overflow because the values make sense in thousands while the variables can count in billions. > Maybe this is something that stems from my programming education - I was > taught in terms of specifications. Any function has a specification > that gives its pre-conditions and its post-conditions. The function > will assume the pre-conditions are valid, and establish the > post-conditions. If you don't ensure you satisfy the pre-conditions > before calling the function, you have no write to expect any know > behaviour at all from the function. This principle is known popularly > as "garbage in, garbage out". It has been understood since the birth of > the programmable computer: > > """ > On two occasions I have been asked, 'Pray, Mr. Babbage, if you put into > the machine wrong figures, will the right answers come out?' I am not > able rightly to apprehend the kind of confusion of ideas that could > provoke such a question. > """ Yes and I want to turn the language full of specified undefined behaviors and contradictions and useless features and defects into programs where there are zero. When wrong figures are put into my programs then I want the program to give answers that follow from those and when contradicting figures are put in then I want my programs to refuse in civil manner. For me quarter of good cases working is not good enough quality. And I'm frustrated when I can't find a way to use it and have to use some kind of nonconforming hacks by compiler vendor. > If you want to say that some programmers don't know that integer > overflow is undefined behaviour, and think it wraps, then blame the way > C and C++ is taught and what the books say, and do something about that > - don't try to dumb down and water out the language. A language that does not have simple features nor convenient ways to implement such is dumbed down by its makers, not by me. > > > >> Actually, it is worth looking at some gcc (or clang) generated code with > >> -ftrapv and -fsanitize=signed-integer-overflow, perhaps with > >> <https://gotbolt.org>, to see just host costly trapping semantics can > >> be. They are very far from negligible. > > > > I have looked and measured its actual impact quite a lot. My > > thinking of it (is surely biased but it) revolves around handful of > > points. > > > > 1) It is about default behavior, in most code its efficiency does > > not matter and for where it matters there indeed *must* be > > alternatives. > > C++ (and C) are often chosen because of their efficiency. If you start > adding run-time tests everywhere, you lose that. Why would you then use > C and C++ at all? If you want extra safety and are willing to pay the > efficiency price, there are other languages to choose from - such as > Java or C#. When you choose to program in C or C++, you are accepting a > responsibility to program carefully and correctly. You are picking a > language that trusts the programmer. Why would you then want the > language or compiler to tell you "I /know/ you claim to be a good > programmer who knows the language and codes carefully - but I don't > believe you, and I'm going to nanny you all the way" ? The languages C and C++ have ages ago stopped trusting me. When I write "register" then they treat like I actually meant "I don't want pointers to it" and when I write "inline" then they read that "I want to define it in header file". English is yes my 4th language but did I really write that? > And once you start saying "C++ programmers can't be trusted to write > expressions that don't overflow", where do you stop? Can you trust them > to use pointers, or do you want run-time checks on all uses of pointers? > Can you trust them to use arrays? Function pointers? Memory > allocation? Multi-threading? There are many, many causes of faults and > bugs in C++ programs that are going to turn up a lot more often than > integer overflows (at least in the 32-bit world - most calculations > don't come close to that limit). Sometimes I want to write code where overflow is not my programming error but allowable contradiction in input data. There I want to throw or to result with INF on overflow. In similar manner like I want it to throw or to result with NaN when kilograms were requested to add to meters or to subtract from degrees of angle or diameter of 11-th apple from 10 is requested. Choice between if I want silent or trapping failures depends on if I want to process the whole data regardless of inconsistencies or constraint violations in it or to interrupt on first such problem in data. Don't such use-cases make sense? > > > > > 2) Efficiency of sub-steps of processing usually does matter > > where we intensively process lot of different data. With lot of data > > we do hit memory latency. Processing has been for decades so > > much cheaper that it can be worth to reduce memory latency > > problems by adding even more processing. For example 1:4 > > uncompressing is faster than copy. > > Note: it is ultra rare case where speed of memcpy is our actual > > bottleneck and not stupidity of copying same data over and > > over too lot or even copying it at all. Same is with processing > > same thing pointlessly over and over. > > > > 3) World evolves. The Swift, Rust, Go, and D communities > > already ask for hardware support for trapping integer > > conversions and trapping arithmetic. People like the languages. > > If hardware starts to support it better then C++ will seem > > backwards without convenient ways to use trapping integers > > in production code. > > I have nothing against using trapping integer arithmetic in cases where > it is useful. But it should only be as an active choice - either by > choosing special types in the code, or by enabling debug options in the > tools. > > And hardware-assisted trapping cannot reach the efficiency of having > overflow as undefined behaviour, or even of wrapping, precisely for the > reasons I gave above about optimising "x + 1 - 1". Currently there are outright nothing. Integer math is in same state (or even worse) than it was in eighties. > > > > 4) Compilers will evolve. What happened to "register" or > > "inline"? Same can happen with usage of current "assume > > that it does not overflow" operations. Just make those not > > default but performance optimizations like register and > > inline. > > > >>>>> For wrap, snap and "compiler may assume that the operation > >>>>> does not overflow" cases I would like new operators. > >>>>> > >>>> > >>>> I suggested new types for the different behaviour, but of course it is > >>>> the operations that have the behaviour, not the types. However, I can't > >>>> see a convenient way to specify overflow behaviour on operations - using > >>>> types is the best balance between flexibility and legible code. > >>> > >>> I mean totally new "advanced" operators like (A +% B) or (C +^ D). > >>> Yes there will be precedence (and may be associativity etc.) > >>> to define but it is business as usual and not some show-stopper > >>> issue. In some languages (like Swift) it is done and it seems to > >>> work fine. > >>> > >> > >> Ah, okay. I think there is a big risk of confusion here, and for people > >> to forget which operators do what. (There is also the risk of > >> accidentally writing smilies in your code!). > > > > It is not that. We see wrapping and saturating is used rarely. > > And thus it should be written explicitly, with types that have names. > Symbol combinations are easily mixed up and forgotten, especially if > they are rarely used. > > One option - which could easily be implemented in C++ of today - would > be to write "x + wrapping + y" as a wrapping addition operator. I see that I technically mostly use wrapping to implement trapping, snapping or otherwise refusing math. The code does make everybody's eyeballs to bleed (sorry if you happen to be fan of those __builtin_add_overflow things) but if there was any better way to have refusing math I would not touch wrapping math at all. Robert Ramey started to write his safe throwing integer library decade ago and it still isn't added to boost I think. > > Also wrapping is on half of cases used without need where > > it can confuse like "for (unsigned u = 10; u < 11; --u)". > > That is an example of well-defined behaviour that is void of meaning. > > > There will not be lot of mixed usages, just sometimes. > > > >> I am happier with the type-based solution, and simply refusing to > >> compile combinations of types that don't make sense (like adding a > >> wrapping type and a saturation type). Undefined or unspecified > >> behaviour types can be silently promoted to other more defined behaviour > >> as needed. > > > > That saturating type perhaps has to be separate type indeed. It > > will have "magical" values and so needs separate protection. > > On rest of cases operators feel to be best. About too implicit > > conversions ... it is another source of hard-to-notice defects. > > > > I would be careful about providing implicit conversions. > > >> That also has the advantage that it can be done today, with current C++. > > > > Life has shown that library features (or even worse "debugging tools") > > as opposed to language features will be adopted slowly by programmers > > and the compiler writers are even slower to start thinking in correct > > direction. > > > > Life has shown that library features are precisely how C++ has evolved > in the last decade or two - language features have mostly been added in > order to make library features safer to use, easier to use, more > efficient, or easier to implement. The next big leap for the C++ > language - metaclasses - is precisely so that we can write libraries > that handle things that would previously need language changes. Too slowly and too lot into useless semantic garbage. At least std::byte gets useful in C++20. We may finally assign a whopping char to it without UB on half of the cases. :D https://wg21.cmeerw.net/cwg/issue2338 So there are tiny progresses and good news all the time.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-11-10 13:17 +0100 |
| Message-ID | <qq8v49$ncg$1@dont-email.me> |
| In reply to | #69663 |
On 08/11/2019 21:08, Öö Tiib wrote: > On Friday, 8 November 2019 15:03:54 UTC+2, David Brown wrote: >> On 08/11/2019 11:01, Öö Tiib wrote: >>> On Wednesday, 6 November 2019 22:50:30 UTC+2, David Brown wrote: >>>> On 06/11/2019 14:26, Öö Tiib wrote: >>>>> On Wednesday, 6 November 2019 00:00:16 UTC+2, David Brown wrote: >>>>>> On 05/11/2019 18:02, Öö Tiib wrote: >>>>>> >>>>>>> * trap (overflow that signals or throws) helps to find programming >>>>>>> errors most reliably and quickly >>>>>> >>>>>> Agreed (where "trap" could mean any kind of notification, exception, >>>>>> error log, etc.). But this is something you might only want during >>>>>> debugging - it is of significant efficiency cost. >>>>> >>>>> Indeed, majority of programming errors should be found during >>>>> debugging. >>>>> >>>>>>> I myself would like most current operators to trap on overflow >>>>>>> (by raising SIGFPE or throwing std::overflow_error) both for >>>>>>> signed and unsigned. >>>>>> >>>>>> I like that in debugging or finding problems - with tools like >>>>>> sanitizers. But I would not want that in normal code. With this kind >>>>>> of semantics, the compiler can't even simplify "x + 1 - 1" to "x". >>>>> >>>>> It may be can or may be can not that depends on wording. >>>>> I have not really thought it thru how to word the semantics >>>>> precisely. The major purpose is to get errors when program >>>>> is actually storing value into type where it does not fit (IOW >>>>> really overflows). >>>> >>>> It is possible to consider intermediary results as "infinite precision", >>>> which would give you that optimisation. But how would you treat: >>>> >>>> x = x + 1; >>>> x = x - 1; >>>> >>>> Would that cause a trap if x started at 0x3ffffff (assuming 32-bit int)? >>>> What if "x" is held in a register rather than stored in memory? There >>>> are lots of possible inconsistencies here. (If it is any guide, gcc >>>> with "-ftrapv" optimises the two statements into "x". With >>>> "-fsanitize=signed-integer-overflow", the single expression "x + 1 - 1" >>>> is simplified to "x", but the two statements lead to checks.) >>> >>> Is it all very similar to issue like where compiler uses 80 bit >>> long double (as best supported by hardware) to do mid-way >>> double arithmetics and so the end result does not saturate into >>> INF or -INF on that platform but it does on other that uses >>> 64 bit double all the way. >>> >> >> Yes - and that is a real mess for standardisation and repeatability. >> It's okay if you are not bothered about the portability and >> repeatability of your floating point calculations, and are happy to >> accept that an unrelated change in one part of your program can lead to >> different results somewhere else just because it changed when floating >> point registers get moved out into the stack. If that's fine, you can >> use "-ffast-math" or equivalent switches and tell your compiler it is >> free to make such code. (Personally, I use "-ffast-math" in my own code >> - but it is not something everyone wants.) > > Yes, and for me it is fine if standard requires "x + 1 - 1" to trap > if x + 1 does overflow. Compilers will add their fast math options > in eye-blink anyway. I am not at all keen on the idea of the standards defining certain behaviour and then compilers having flags to disregard those definitions - that is, I think, a terrible idea. If trapping were to be added to the standards, it would be much better if the standards offered a user-selectable choice (I suppose via pragmas). Remember, features like gcc's "-ffast-math" do not instruct the compiler to ignore parts of the /C/ standard - they ignore parts of the IEEE floating point standards. This is a very different matter. As far as I know, "gcc -ffast-math" is no more non-compliant than "gcc". > >> I do not want that situation in integer code. > > Then there won't be. I am entirely confident that trapping on overflow will never be required by the C or C++ standards anyway, so this is hypothetical. But it is feasible that there could be optional support defined (such as via a new library section in C++), and there I would want the consistency. > >> I am much happier with the function of >> "-fsanitize=signed-integer-overflow" here - it generates more checks, >> less efficient code, but the functionality is clear and consistent. >> I'll use that when I am happy to take the performance hit in the name of >> debugging code. > > It is not trapping math there but debugging tool that caught "undefined > behavior". It does not help me on cases when I need trapping maths. > Trapping maths can be handled in many ways - kill with an error message is often useful in debugging, but as you say it is not useful for handling it within the program. Throwing an exception, calling a trap handler, returning a signalling NaN, are other alternatives. My point was that I wanted the semantics of -fsanitize=signed-integer-overflow for detecting the overflow - how that overflow is another matter. >> >>> I feel dealing with such issue" to be *lot* easier than dealing >>> with utter undefined behavior (that all such examples are by >>> current scripture). For me every solution is better than >>> undefined behavior. >> >> The whole point is that you /don't/ hit undefined behaviour. > > The whole issue that you seemingly don't understand is that there are > cases (and those seem to be majority) where I don't need to have undefined > behaviors nor wrapping behaviors nor arbitrarily growing precisions. > I want it to trap by default and sometimes to have snapping behavior. > > But I have either undefined behavior with signed or wrapping > behavior with unsigned and non-portable intrinsic functions. > So I have to choose what hack is uglier to write trapping or > snapping myself manually and everyone else in same situation > like me has to do same. I am all in favour of choice, but there are a few things I disagree with you. First, you seem to want trapping to be the default in the standards - that is a very costly idea to impose on everyone else, as well as being rather difficult to specify and implement. Secondly, you seem to want this for all arithmetic. I'm fine with using trapping explicitly in code when it is particular useful - that would work naturally with exceptions in C++. But I would want the lower-level code that is not going to overflow, to be free from the cost of this checking. (Compilers might be able to eliminate some of the overhead, but they won't get everything.) Thirdly, you seem to think trapping is useful semantics in general - I disagree. There are times when it could be convenient in code where overflow is a realistic but unlikely scenario, mostly it sounds like you are happy with releasing code that is buggy as long as the consequences of the bugs are somewhat limited. I don't like that attitude, and I don't think you do either - so there is maybe still something I don't understand here. > >> To me, undefined behaviour is /better/ than the alternatives for most >> purposes. It helps me write better and more correct code, and as a >> bonus it is more efficient. > > It is better only when I know that it can no way overflow because the > values make sense in thousands while the variables can count in billions. To me, that should /always/ be the case - though I am quite happy with values that only make sense up to a thousand with a variable that can count to a thousand. I always want to know the limits of my values, and there is no need to work with bigger sizes than needed. > >> Maybe this is something that stems from my programming education - I was >> taught in terms of specifications. Any function has a specification >> that gives its pre-conditions and its post-conditions. The function >> will assume the pre-conditions are valid, and establish the >> post-conditions. If you don't ensure you satisfy the pre-conditions >> before calling the function, you have no write to expect any know >> behaviour at all from the function. This principle is known popularly >> as "garbage in, garbage out". It has been understood since the birth of >> the programmable computer: >> >> """ >> On two occasions I have been asked, 'Pray, Mr. Babbage, if you put into >> the machine wrong figures, will the right answers come out?' I am not >> able rightly to apprehend the kind of confusion of ideas that could >> provoke such a question. >> """ > > Yes and I want to turn the language full of specified undefined > behaviors and contradictions and useless features and defects into > programs where there are zero. You can't. It won't work. (Well, you can probably deal with contradictions in the language, though I don't know what you are referring to here.) Languages /always/ have undefined behaviours. And there is rarely a benefit in turning undefined behaviour into defined behaviour unless that behaviour is correct. If a program tries to calculate "foo(x)", and the calculation overflows and gives the wrong answer, the program is broken. Giving a definition to the overflow - whether it is wrapping, trapping, throwing, saturating - does not make the program correct. It is still broken. Some types of defined behaviour can make it easier to find the bug during testing - such as error messages on overflows. Some make it harder to find the bugs, such as wrapping. Some make it easier to limit the damage from the bugs, such as throwing an exception. None change the fact that the program has a bug. And if you look at the language, there are /loads/ of undefined behaviours. Integer overflows are just a tiny one, and one that has become a good deal less common since 32-bit int became the norm. C++ will still let programmers shoot themselves in the foot in all sorts of ways - worrying about the splinters in their fingers will not fix the hole in their feet. > When wrong figures > are put into my programs then I want the program to give > answers that follow from those and when contradicting figures > are put in then I want my programs to refuse in civil manner. That is fair enough - that is why you should check the figures that are put into the program, not the calculations in the good code that you have written. > For me quarter of good cases working is not good > enough quality. And I'm frustrated when I can't find a way to > use it and have to use some kind of nonconforming hacks by > compiler vendor. > >> If you want to say that some programmers don't know that integer >> overflow is undefined behaviour, and think it wraps, then blame the way >> C and C++ is taught and what the books say, and do something about that >> - don't try to dumb down and water out the language. > > A language that does not have simple features nor convenient ways to > implement such is dumbed down by its makers, not by me. > No language covers everything that all programmers want - there are always compromises. >>> >>>> Actually, it is worth looking at some gcc (or clang) generated code with >>>> -ftrapv and -fsanitize=signed-integer-overflow, perhaps with >>>> <https://gotbolt.org>, to see just host costly trapping semantics can >>>> be. They are very far from negligible. >>> >>> I have looked and measured its actual impact quite a lot. My >>> thinking of it (is surely biased but it) revolves around handful of >>> points. >>> >>> 1) It is about default behavior, in most code its efficiency does >>> not matter and for where it matters there indeed *must* be >>> alternatives. >> >> C++ (and C) are often chosen because of their efficiency. If you start >> adding run-time tests everywhere, you lose that. Why would you then use >> C and C++ at all? If you want extra safety and are willing to pay the >> efficiency price, there are other languages to choose from - such as >> Java or C#. When you choose to program in C or C++, you are accepting a >> responsibility to program carefully and correctly. You are picking a >> language that trusts the programmer. Why would you then want the >> language or compiler to tell you "I /know/ you claim to be a good >> programmer who knows the language and codes carefully - but I don't >> believe you, and I'm going to nanny you all the way" ? > > The languages C and C++ have ages ago stopped trusting me. When I write > "register" then they treat like I actually meant "I don't want pointers > to it" and when I write "inline" then they read that "I want to > define it in header file". English is yes my 4th language but did I > really write that? Yes, you did. At least, that's what the definition of the languages says. The words used in a programming language don't always correspond to their normal meanings in English. Nor do they always remain the same as they move from compiler extensions through to standards. It is unfortunate, but true - and it is the programmer's job to write in a way that is clear to the reader /and/ precise in the language. (Incidentally, you write better English many people I know who have it as their first language. And it is not as if Estonian is close to English!) > >> And once you start saying "C++ programmers can't be trusted to write >> expressions that don't overflow", where do you stop? Can you trust them >> to use pointers, or do you want run-time checks on all uses of pointers? >> Can you trust them to use arrays? Function pointers? Memory >> allocation? Multi-threading? There are many, many causes of faults and >> bugs in C++ programs that are going to turn up a lot more often than >> integer overflows (at least in the 32-bit world - most calculations >> don't come close to that limit). > > Sometimes I want to write code where overflow is not my programming > error but allowable contradiction in input data. There I want to throw or > to result with INF on overflow. That should be handled by C++ classes that have such semantics on overflow - which you use explicitly when you want that behaviour. I'd be happy to see a standard library with this behaviour. > In similar manner like I want it to > throw or to result with NaN when kilograms were requested > to add to meters or to subtract from degrees of angle or diameter > of 11-th apple from 10 is requested. That is a completely different matter. Personally, I would not want an exception or a NaN here - I would want a compile time error. Again, this can be handled perfectly well in C++ using strong class types. And again, it would be nice to see such libraries standardised. In both these cases, I think concepts will make the definition and use of such class template libraries a good deal neater. > Choice between if I want silent > or trapping failures depends on if I want to process the whole data > regardless of inconsistencies or constraint violations in it or to > interrupt on first such problem in data. Don't such use-cases make sense? Yes, which is why it is far better to deal with it using explicit choices of the types used rather than making it part of the language. > >> >>> >>> 2) Efficiency of sub-steps of processing usually does matter >>> where we intensively process lot of different data. With lot of data >>> we do hit memory latency. Processing has been for decades so >>> much cheaper that it can be worth to reduce memory latency >>> problems by adding even more processing. For example 1:4 >>> uncompressing is faster than copy. >>> Note: it is ultra rare case where speed of memcpy is our actual >>> bottleneck and not stupidity of copying same data over and >>> over too lot or even copying it at all. Same is with processing >>> same thing pointlessly over and over. >>> >>> 3) World evolves. The Swift, Rust, Go, and D communities >>> already ask for hardware support for trapping integer >>> conversions and trapping arithmetic. People like the languages. >>> If hardware starts to support it better then C++ will seem >>> backwards without convenient ways to use trapping integers >>> in production code. >> >> I have nothing against using trapping integer arithmetic in cases where >> it is useful. But it should only be as an active choice - either by >> choosing special types in the code, or by enabling debug options in the >> tools. >> >> And hardware-assisted trapping cannot reach the efficiency of having >> overflow as undefined behaviour, or even of wrapping, precisely for the >> reasons I gave above about optimising "x + 1 - 1". > > Currently there are outright nothing. Integer math is in same state (or > even worse) than it was in eighties. Which is fine for many people. And since hardware assistance would give you very little benefit for what you want here, it is not surprising that it does not exist. (Hardware assistance could be a big help in a wide variety of other undefined behaviour, bugs, and low-level features in C and C++, but that is a different discussion.) > >>> >>> 4) Compilers will evolve. What happened to "register" or >>> "inline"? Same can happen with usage of current "assume >>> that it does not overflow" operations. Just make those not >>> default but performance optimizations like register and >>> inline. >>> >>>>>>> For wrap, snap and "compiler may assume that the operation >>>>>>> does not overflow" cases I would like new operators. >>>>>>> >>>>>> >>>>>> I suggested new types for the different behaviour, but of course it is >>>>>> the operations that have the behaviour, not the types. However, I can't >>>>>> see a convenient way to specify overflow behaviour on operations - using >>>>>> types is the best balance between flexibility and legible code. >>>>> >>>>> I mean totally new "advanced" operators like (A +% B) or (C +^ D). >>>>> Yes there will be precedence (and may be associativity etc.) >>>>> to define but it is business as usual and not some show-stopper >>>>> issue. In some languages (like Swift) it is done and it seems to >>>>> work fine. >>>>> >>>> >>>> Ah, okay. I think there is a big risk of confusion here, and for people >>>> to forget which operators do what. (There is also the risk of >>>> accidentally writing smilies in your code!). >>> >>> It is not that. We see wrapping and saturating is used rarely. >> >> And thus it should be written explicitly, with types that have names. >> Symbol combinations are easily mixed up and forgotten, especially if >> they are rarely used. >> >> One option - which could easily be implemented in C++ of today - would >> be to write "x + wrapping + y" as a wrapping addition operator. > > I see that I technically mostly use wrapping to implement trapping, > snapping or otherwise refusing math. The code does make everybody's > eyeballs to bleed (sorry if you happen to be fan of those > __builtin_add_overflow things) but if there was any better way to have > refusing math I would not touch wrapping math at all. I don't think anyone will tell you __builtin_add_overflow leads to pretty code! But you write these sorts of things once, and hide them away in a library so that the use of the functions is simple and clear. > Robert Ramey started to write his safe throwing integer library decade > ago and it still isn't added to boost I think. > >>> Also wrapping is on half of cases used without need where >>> it can confuse like "for (unsigned u = 10; u < 11; --u)". >> >> That is an example of well-defined behaviour that is void of meaning. >> >>> There will not be lot of mixed usages, just sometimes. >>> >>>> I am happier with the type-based solution, and simply refusing to >>>> compile combinations of types that don't make sense (like adding a >>>> wrapping type and a saturation type). Undefined or unspecified >>>> behaviour types can be silently promoted to other more defined behaviour >>>> as needed. >>> >>> That saturating type perhaps has to be separate type indeed. It >>> will have "magical" values and so needs separate protection. >>> On rest of cases operators feel to be best. About too implicit >>> conversions ... it is another source of hard-to-notice defects. >>> >> >> I would be careful about providing implicit conversions. >> >>>> That also has the advantage that it can be done today, with current C++. >>> >>> Life has shown that library features (or even worse "debugging tools") >>> as opposed to language features will be adopted slowly by programmers >>> and the compiler writers are even slower to start thinking in correct >>> direction. >>> >> >> Life has shown that library features are precisely how C++ has evolved >> in the last decade or two - language features have mostly been added in >> order to make library features safer to use, easier to use, more >> efficient, or easier to implement. The next big leap for the C++ >> language - metaclasses - is precisely so that we can write libraries >> that handle things that would previously need language changes. > > Too slowly and too lot into useless semantic garbage. At least > std::byte gets useful in C++20. We may finally assign a whopping char > to it without UB on half of the cases. :D > https://wg21.cmeerw.net/cwg/issue2338 > So there are tiny progresses and good news all the time. >
[toc] | [prev] | [next] | [standalone]
| From | "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> |
|---|---|
| Date | 2019-11-10 14:37 +0100 |
| Message-ID | <qq93qu$ka8$1@dont-email.me> |
| In reply to | #69699 |
On 10.11.2019 13:17, David Brown wrote: > [snip] > Remember, features like gcc's "-ffast-math" do not instruct the compiler > to ignore parts of the /C/ standard - they ignore parts of the IEEE > floating point standards. This is a very different matter. As far as I > know, "gcc -ffast-math" is no more non-compliant than "gcc". Possibly you're talking about C only, I'm not sure of the wider thread context here. Sorry for jumping in. However, with C++ the `-ffast-math` option for g++ is in conflict with the standard because `numeric_limits` then still reports IEEE 754 compliance, while e.g. NaN comparisons are then non-compliant. I remember once engaging in a heated (!) debate with Gabriel Dos Reis about this, so it's possible to have different opinions about it, even among knowledgeable people, for certain. IMO the fast and the compliant floating point types should at least by default be differently named types, not the same type with different behavior depending on an option. So I regard it as a quite nasty design bug. - Alf
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-11-10 17:08 +0100 |
| Message-ID | <qq9cli$9ee$1@dont-email.me> |
| In reply to | #69700 |
On 10/11/2019 14:37, Alf P. Steinbach wrote: > On 10.11.2019 13:17, David Brown wrote: >> [snip] >> Remember, features like gcc's "-ffast-math" do not instruct the >> compiler to ignore parts of the /C/ standard - they ignore parts of >> the IEEE floating point standards. This is a very different matter. >> As far as I know, "gcc -ffast-math" is no more non-compliant than "gcc". > > Possibly you're talking about C only, I'm not sure of the wider thread > context here. > > Sorry for jumping in. Feel free! > > However, with C++ the `-ffast-math` option for g++ is in conflict with > the standard because `numeric_limits` then still reports IEEE 754 > compliance, while e.g. NaN comparisons are then non-compliant. Fair enough - that's a good point. > > I remember once engaging in a heated (!) debate with Gabriel Dos Reis > about this, so it's possible to have different opinions about it, even > among knowledgeable people, for certain. I could imagine a difference of opinion here - "gcc -ffast-math" has IEEE standard formats but not IEEE standard operations. > > IMO the fast and the compliant floating point types should at least by > default be differently named types, not the same type with different > behavior depending on an option. The compiler does require an explicit option here for non-IEEE operations - it is (baring bugs or missing features - I don't know the details) IEEE standard by default. There is always a balance on these things. "-ffast-math" can be very much faster than IEEE standard behaviour on many platforms, and is perfectly acceptable for most people's use of floating point. Why should the majority have slower code (and perhaps worse accuracy) just because some few scientific users need identical results consistent across platforms? I'd actually say my preferred solution is that strict IEEE types should be a different, specific types that programmers can pick explicitly, while "-ffast-math" equivalent could be the default. The "numeric_limits" could differentiate between the representation and the operations (the same should apply to signed integers, differentiating between representation and wrapping overflow behaviour), and implementations should set the values here according to what they guarantee regardless of flags. > > So I regard it as a quite nasty design bug. > "Bug" implies a mistake. This is a design choice, on which people disagree - not a bug.
[toc] | [prev] | [next] | [standalone]
| From | Manfred <noname@invalid.add> |
|---|---|
| Date | 2019-11-10 18:34 +0100 |
| Message-ID | <qq9hmi$8kt$1@gioia.aioe.org> |
| In reply to | #69703 |
On 11/10/19 5:08 PM, David Brown wrote: > On 10/11/2019 14:37, Alf P. Steinbach wrote: >> On 10.11.2019 13:17, David Brown wrote: >>> [snip] > >> >> IMO the fast and the compliant floating point types should at least by >> default be differently named types, not the same type with different >> behavior depending on an option. > > The compiler does require an explicit option here for non-IEEE > operations - it is (baring bugs or missing features - I don't know the > details) IEEE standard by default. > > There is always a balance on these things. "-ffast-math" can be very > much faster than IEEE standard behaviour on many platforms, and is > perfectly acceptable for most people's use of floating point. Why > should the majority have slower code (and perhaps worse accuracy) just > because some few scientific users need identical results consistent > across platforms? It's not that simple (and -ffast-math does not improve accuracy), see below. > > I'd actually say my preferred solution is that strict IEEE types should > be a different, specific types that programmers can pick explicitly, > while "-ffast-math" equivalent could be the default. The fact is that -ffast-math can cause loss of precision, so it can introduce nasty bugs in existing code that assumes IEEE conformance. Since managing accuracy errors is among the most common causes of floating point bugs, the majority of programmers is better off without -ffast-math. If you want the extra speed, you need to know what you are doing (and that it doesn't come for free) so you'd better ask for it explicitly. By the way, with floating point there are a number of techniques to be considered that improve efficiency before tweaking compiler flags. The > "numeric_limits" could differentiate between the representation and the > operations (the same should apply to signed integers, differentiating > between representation and wrapping overflow behaviour), and > implementations should set the values here according to what they > guarantee regardless of flags. > >> >> So I regard it as a quite nasty design bug. >> > > "Bug" implies a mistake. This is a design choice, on which people > disagree - not a bug.
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2019-11-11 07:48 +1300 |
| Message-ID | <h2r4c6F4cl5U8@mid.individual.net> |
| In reply to | #69704 |
On 11/11/2019 06:34, Manfred wrote: >> >> I'd actually say my preferred solution is that strict IEEE types should >> be a different, specific types that programmers can pick explicitly, >> while "-ffast-math" equivalent could be the default. > > The fact is that -ffast-math can cause loss of precision, so it can > introduce nasty bugs in existing code that assumes IEEE conformance. > Since managing accuracy errors is among the most common causes of > floating point bugs, the majority of programmers is better off without > -ffast-math. > If you want the extra speed, you need to know what you are doing (and > that it doesn't come for free) so you'd better ask for it explicitly. > By the way, with floating point there are a number of techniques to be > considered that improve efficiency before tweaking compiler flags. With ARM processors which use NEON, -ffast-math is required if you want to vectorise floating point operation. This is because the hardware isn't IEEE compliant. This was a bit of a pain for us which resulted in lots of extra testing.... -- Ian.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-11-10 21:31 +0100 |
| Message-ID | <qq9s31$cbd$1@dont-email.me> |
| In reply to | #69704 |
On 10/11/2019 18:34, Manfred wrote: > On 11/10/19 5:08 PM, David Brown wrote: >> On 10/11/2019 14:37, Alf P. Steinbach wrote: >>> On 10.11.2019 13:17, David Brown wrote: >>>> [snip] > >> >>> >>> IMO the fast and the compliant floating point types should at least >>> by default be differently named types, not the same type with >>> different behavior depending on an option. >> >> The compiler does require an explicit option here for non-IEEE >> operations - it is (baring bugs or missing features - I don't know the >> details) IEEE standard by default. >> >> There is always a balance on these things. "-ffast-math" can be very >> much faster than IEEE standard behaviour on many platforms, and is >> perfectly acceptable for most people's use of floating point. Why >> should the majority have slower code (and perhaps worse accuracy) just >> because some few scientific users need identical results consistent >> across platforms? > > It's not that simple (and -ffast-math does not improve accuracy), see > below. > >> >> I'd actually say my preferred solution is that strict IEEE types >> should be a different, specific types that programmers can pick >> explicitly, while "-ffast-math" equivalent could be the default. > > The fact is that -ffast-math can cause loss of precision, so it can > introduce nasty bugs in existing code that assumes IEEE conformance. -ffast-math /can/ cause loss of precision, but it can also improve precision. If you write "(x + 1e50) - 1e50", -ffast-math will let the compiler generate code for "x" while IEEE conformance requires the addition and subtraction, losing you all your precision of x (assuming x is small compared to 1e50). The key point is that it doesn't keep the consistency required by IEEE. And of course if you have code that assumes IEEE conformance and needs it for correctness, and you turn off conformance, then you risk a result that doesn't work. You can't use -ffast-math unless you know the code doesn't need IEEE conformance. So it /is/ that simple, and that obvious. And while I say this is /my/ preferred solution, I can quite happily appreciate that other people prefer something else. (And realistically, I know it takes a huge incentive before the status quo is changed. Even if it turns out, as I think is the case, that most programs would run correctly and more efficiently with -ffast-math, that does not mean the default is likely to change.) > Since managing accuracy errors is among the most common causes of > floating point bugs, the majority of programmers is better off without > -ffast-math. I don't think most programs care unduly about the accuracy of floating point calculations. I think most calculations in floating point have low enough accuracy needs that you can use doubles and accept that the answer is approximate but good enough. And I think most programmers are totally unaware of the details of IEEE and how to use the features it gives in getting slightly more control of error margins. But I freely admit that is gut feeling, not based on any kind of surveys, statistics, etc. > If you want the extra speed, you need to know what you are doing (and > that it doesn't come for free) so you'd better ask for it explicitly. It can make a very large difference, depending on the target processor and the type of code. (Many small processors with floating point hardware have hardware that supports "ordinary" floats, but does not handle infinities, NaNs, infinitesimals, etc. -ffast-math can generated code that runs in a few hardware instructions while without it you need library calls and hundreds of instructions. Yes, it can be /that/ big a difference - and that is personal experience, not gut feeling.) > By the way, with floating point there are a number of techniques to be > considered that improve efficiency before tweaking compiler flags. Of course. > > > The >> "numeric_limits" could differentiate between the representation and >> the operations (the same should apply to signed integers, >> differentiating between representation and wrapping overflow >> behaviour), and implementations should set the values here according >> to what they guarantee regardless of flags. >> >>> >>> So I regard it as a quite nasty design bug. >>> >> >> "Bug" implies a mistake. This is a design choice, on which people >> disagree - not a bug. >
[toc] | [prev] | [next] | [standalone]
| From | Bo Persson <bo@bo-persson.se> |
|---|---|
| Date | 2019-11-04 23:55 +0100 |
| Message-ID | <h2boieFkf17U1@mid.individual.net> |
| In reply to | #69548 |
On 2019-11-04 at 20:48, Bonita Montero wrote: > What would realls speak against that numieric_limits<type> would include > a flag whether a type has a two's complement and maybe another flag that > says that a type has a two's complement wrap-around? Possibly that in C++20 all signed integers *are* two's complement. :-) https://wg21.link/P0907
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-11-05 10:32 +0100 |
| Message-ID | <qprfju$2r5$2@dont-email.me> |
| In reply to | #69554 |
On 04/11/2019 23:55, Bo Persson wrote: > On 2019-11-04 at 20:48, Bonita Montero wrote: >> What would realls speak against that numieric_limits<type> would include >> a flag whether a type has a two's complement and maybe another flag that >> says that a type has a two's complement wrap-around? > > Possibly that in C++20 all signed integers *are* two's complement. :-) > > https://wg21.link/P0907 > Two's complement representation, but /not/ wrapping.
[toc] | [prev] | [next] | [standalone]
| From | Siri Cruise <chine.bleu@yahoo.com> |
|---|---|
| Date | 2019-11-04 19:55 -0700 |
| Message-ID | <chine.bleu-5DC1AD.19552804112019@reader.eternal-september.org> |
| In reply to | #69548 |
In article <qppva0$cbj$1@news.albasani.net>, Bonita Montero <Bonita.Montero@gmail.com> wrote: > What would realls speak against that numieric_limits<type> would include > a flag whether a type has a two's complement and maybe another flag that > says that a type has a two's complement wrap-around? #define ONESCOMPLEMENT (-1==~1) #define TWOSCOMPLEMENT (-1==~0) -- :-<> 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]
| From | "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> |
|---|---|
| Date | 2019-11-05 05:52 +0100 |
| Message-ID | <qpqv6g$kc3$1@dont-email.me> |
| In reply to | #69555 |
On 05.11.2019 03:55, Siri Cruise wrote: > In article <qppva0$cbj$1@news.albasani.net>, > Bonita Montero <Bonita.Montero@gmail.com> wrote: > >> What would realls speak against that numieric_limits<type> would include >> a flag whether a type has a two's complement and maybe another flag that >> says that a type has a two's complement wrap-around? > > #define ONESCOMPLEMENT (-1==~1) > #define TWOSCOMPLEMENT (-1==~0) Nice idea. But please use `constexpr` or `const` declarations, not macros. Using macros conveys the idea that macros are a reasonable solution to the problem of naming a compile time constant. - Alf
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2019-11-05 18:17 +1300 |
| Message-ID | <h2cevnFa2cqU11@mid.individual.net> |
| In reply to | #69556 |
On 05/11/2019 17:52, Alf P. Steinbach wrote: > On 05.11.2019 03:55, Siri Cruise wrote: >> In article <qppva0$cbj$1@news.albasani.net>, >> Bonita Montero <Bonita.Montero@gmail.com> wrote: >> >>> What would realls speak against that numieric_limits<type> would include >>> a flag whether a type has a two's complement and maybe another flag that >>> says that a type has a two's complement wrap-around? >> >> #define ONESCOMPLEMENT (-1==~1) >> #define TWOSCOMPLEMENT (-1==~0) > > Nice idea. > > But please use `constexpr` or `const` declarations, not macros. > > Using macros conveys the idea that macros are a reasonable solution to > the problem of naming a compile time constant. :) -- Ian.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2019-11-09 05:55 -0800 |
| Message-ID | <86tv7dcfxr.fsf@linuxsc.com> |
| In reply to | #69556 |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> writes: > On 05.11.2019 03:55, Siri Cruise wrote: > >> In article <qppva0$cbj$1@news.albasani.net>, >> Bonita Montero <Bonita.Montero@gmail.com> wrote: >> >>> What would realls speak against that numieric_limits<type> would include >>> a flag whether a type has a two's complement and maybe another flag that >>> says that a type has a two's complement wrap-around? >> >> #define ONESCOMPLEMENT (-1==~1) >> #define TWOSCOMPLEMENT (-1==~0) > > Nice idea. > > But please use `constexpr` or `const` declarations, not macros. > > Using macros conveys the idea that macros are a reasonable solution to > the problem of naming a compile time constant. Why do C++ fans hate the C preprocessor so much?
[toc] | [prev] | [next] | [standalone]
| From | Siri Cruise <chine.bleu@yahoo.com> |
|---|---|
| Date | 2019-11-09 06:33 -0700 |
| Message-ID | <chine.bleu-31DD77.06334909112019@reader.eternal-september.org> |
| In reply to | #69677 |
In article <86tv7dcfxr.fsf@linuxsc.com>,
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
> "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> writes:
>
> > On 05.11.2019 03:55, Siri Cruise wrote:
> >
> >> In article <qppva0$cbj$1@news.albasani.net>,
> >> Bonita Montero <Bonita.Montero@gmail.com> wrote:
> >>
> >>> What would realls speak against that numieric_limits<type> would include
> >>> a flag whether a type has a two's complement and maybe another flag that
> >>> says that a type has a two's complement wrap-around?
> >>
> >> #define ONESCOMPLEMENT (-1==~1)
> >> #define TWOSCOMPLEMENT (-1==~0)
> >
> > Nice idea.
> >
> > But please use `constexpr` or `const` declarations, not macros.
> >
> > Using macros conveys the idea that macros are a reasonable solution to
> > the problem of naming a compile time constant.
>
> Why do C++ fans hate the C preprocessor so much?
Because C++ is dedicated to new, obscure, ambiguous syntax everytime anyone has
a hangnail.
Do you to ensure a variable is defined before first use? Well, you could
dedicate years of effort to synchronise loaders and compilers with new object
file tables, or
#define variable (*variable_())
type_t* variable_ () {
static lock_t lock = unlocked;
static bool defined = false;
static type_t v;
if (!defined) {
if (!try_lock(lock)) error("circular initialisation");
if (!defined) {
defined = true;
v = (initialisation());
}
unlock(lock);
}
return &v;
}
--
:-<> 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]
Page 4 of 11 — ← Prev page 1 2 3 [4] 5 6 … 11 Next page →
Back to top | Article view | comp.lang.c++
csiph-web