Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #71022 > unrolled thread
| Started by | "Skybuck Flying" <skybuck2000@hotmail.com> |
|---|---|
| First post | 2015-09-21 20:17 +0200 |
| Last post | 2015-09-22 11:23 +0200 |
| Articles | 20 on this page of 145 — 21 participants |
Back to article view | Back to comp.lang.c
How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-21 20:17 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-21 20:43 +0200
Re: How to write this sign function in Delphi. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-09-21 19:51 +0100
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-21 23:26 +0200
Re: How to write this sign function in Delphi. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-09-21 22:47 +0100
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-22 16:29 +0200
Re: How to write this sign function in Delphi. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-09-22 16:11 +0100
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-23 11:18 +0200
Re: How to write this sign function in Delphi. David Brown <david.brown@hesbynett.no> - 2015-09-23 13:01 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-21 20:53 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-21 20:54 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-21 20:58 +0200
Re: How to write this sign function in Delphi. M Philbrook <jamie_ka1lpa@charter.net> - 2015-09-21 18:15 -0400
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-09-21 15:21 -0700
Re: How to write this sign function in Delphi. Robert Wessel <robertwessel2@yahoo.com> - 2015-09-21 17:51 -0500
Re: How to write this sign function in Delphi. James Kuyper <jameskuyper@verizon.net> - 2015-09-21 19:15 -0400
Re: How to write this sign function in Delphi. Robert Wessel <robertwessel2@yahoo.com> - 2015-09-21 23:59 -0500
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-09-22 09:22 -0700
Re: How to write this sign function in Delphi. Keith Thompson <kst-u@mib.org> - 2015-09-22 10:32 -0700
Re: How to write this sign function in Delphi. jt@toerring.de (Jens Thoms Toerring) - 2015-09-22 18:17 +0000
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-09-22 12:25 -0700
Re: How to write this sign function in Delphi. jt@toerring.de (Jens Thoms Toerring) - 2015-09-22 22:33 +0000
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-09-22 15:52 -0700
Re: How to write this sign function in Delphi. raltbos@xs4all.nl (Richard Bos) - 2015-09-22 23:09 +0000
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-09-23 09:07 -0700
Re: How to write this sign function in Delphi. Jorgen Grahn <grahn+nntp@snipabacken.se> - 2015-09-23 16:55 +0000
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-09-23 10:46 -0700
Re: How to write this sign function in Delphi. jt@toerring.de (Jens Thoms Toerring) - 2015-09-23 23:18 +0000
Re: How to write this sign function in Delphi. James Kuyper <jameskuyper@verizon.net> - 2015-09-23 22:29 -0400
Re: How to write this sign function in Delphi. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-09-24 11:09 +0100
Re: How to write this sign function in Delphi. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-09-27 18:23 -0700
Re: How to write this sign function in Delphi. glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-09-28 05:20 +0000
Re: How to write this sign function in Delphi. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-09-27 23:23 -0700
Re: How to write this sign function in Delphi. Richard Heathfield <rjh@cpax.org.uk> - 2015-09-28 09:03 +0100
Re: How to write this sign function in Delphi. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-09-28 01:24 -0700
Re: How to write this sign function in Delphi. Richard Heathfield <rjh@cpax.org.uk> - 2015-09-28 09:32 +0100
Re: How to write this sign function in Delphi. Bartc <bc@freeuk.com> - 2015-09-28 10:22 +0100
Re: How to write this sign function in Delphi. Richard Heathfield <rjh@cpax.org.uk> - 2015-09-28 11:35 +0100
Re: How to write this sign function in Delphi. Keith Thompson <kst-u@mib.org> - 2015-09-28 10:33 -0700
Re: How to write this sign function in Delphi. Richard Heathfield <rjh@cpax.org.uk> - 2015-09-28 18:59 +0100
Re: How to write this sign function in Delphi. Rosario19 <Ros@invalid.invalid> - 2015-09-28 20:09 +0200
Re: How to write this sign function in Delphi. Robert Wessel <robertwessel2@yahoo.com> - 2015-09-28 13:39 -0500
Re: How to write this sign function in Delphi. Richard Heathfield <rjh@cpax.org.uk> - 2015-09-28 20:04 +0100
Re: How to write this sign function in Delphi. Robert Wessel <robertwessel2@yahoo.com> - 2015-09-28 16:43 -0500
Re: How to write this sign function in Delphi. Martin Shobe <martin.shobe@yahoo.com> - 2015-09-28 18:55 -0500
Re: How to write this sign function in Delphi. Robert Wessel <robertwessel2@yahoo.com> - 2015-09-28 19:31 -0500
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-09-28 12:16 -0700
Re: How to write this sign function in Delphi. Keith Thompson <kst-u@mib.org> - 2015-09-28 14:31 -0700
Re: How to write this sign function in Delphi. Robert Wessel <robertwessel2@yahoo.com> - 2015-09-28 16:47 -0500
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-09-29 11:54 -0700
Re: How to write this sign function in Delphi. Robert Wessel <robertwessel2@yahoo.com> - 2015-10-01 00:36 -0500
Re: How to write this sign function in Delphi. raltbos@xs4all.nl (Richard Bos) - 2015-10-02 10:53 +0000
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-02 09:48 -0700
Re: How to write this sign function in Delphi. Robert Wessel <robertwessel2@yahoo.com> - 2015-10-03 11:27 -0500
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-03 12:32 -0700
Re: How to write this sign function in Delphi. Robert Wessel <robertwessel2@yahoo.com> - 2015-10-03 11:26 -0500
Re: How to write this sign function in Delphi. Tim Rentsch <txr@alumni.caltech.edu> - 2015-10-04 16:46 -0700
Re: How to write this sign function in Delphi. Keith Thompson <kst-u@mib.org> - 2015-09-28 14:23 -0700
Re: How to write this sign function in Delphi. Robert Wessel <robertwessel2@yahoo.com> - 2015-09-28 16:52 -0500
Re: How to write this sign function in Delphi. Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-30 01:39 -0700
Re: How to write this sign function in Delphi. Keith Thompson <kst-u@mib.org> - 2015-09-30 12:37 -0700
Re: How to write this sign function in Delphi. glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-09-30 21:28 +0000
Re: How to write this sign function in Delphi. James Kuyper <jameskuyper@verizon.net> - 2015-09-30 17:54 -0400
Re: How to write this sign function in Delphi. glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-01 03:59 +0000
Re: How to write this sign function in Delphi. James Kuyper <jameskuyper@verizon.net> - 2015-10-01 01:42 -0400
Re: How to write this sign function in Delphi. Keith Thompson <kst-u@mib.org> - 2015-09-30 16:20 -0700
Re: How to write this sign function in Delphi. Tim Rentsch <txr@alumni.caltech.edu> - 2015-10-04 16:39 -0700
Re: How to write this sign function in Delphi. glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-09-28 23:23 +0000
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-09-29 09:35 -0700
Re: How to write this sign function in Delphi. raltbos@xs4all.nl (Richard Bos) - 2015-10-02 11:06 +0000
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-02 09:23 -0700
Re: How to write this sign function in Delphi. Martin Shobe <martin.shobe@yahoo.com> - 2015-10-02 12:07 -0500
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-02 10:47 -0700
Re: How to write this sign function in Delphi. Keith Thompson <kst-u@mib.org> - 2015-10-02 17:48 -0700
Re: How to write this sign function in Delphi. Richard Heathfield <rjh@cpax.org.uk> - 2015-10-03 16:46 +0100
Re: How to write this sign function in Delphi. Martin Shobe <martin.shobe@yahoo.com> - 2015-10-05 10:41 -0500
Re: How to write this sign function in Delphi. James Kuyper <jameskuyper@verizon.net> - 2015-09-28 15:31 -0400
Re: How to write this sign function in Delphi. Robert Wessel <robertwessel2@yahoo.com> - 2015-09-28 16:40 -0500
Re: How to write this sign function in Delphi. James Kuyper <jameskuyper@verizon.net> - 2015-09-28 18:17 -0400
Re: How to write this sign function in Delphi. Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-30 02:49 -0700
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-09-30 06:27 -0700
Re: How to write this sign function in Delphi. Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-29 10:43 -0700
Re: How to write this sign function in Delphi. glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-09-28 22:51 +0000
Re: How to write this sign function in Delphi. Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-30 02:11 -0700
Re: How to write this sign function in Delphi. glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-09-28 22:48 +0000
Re: How to write this sign function in Delphi. Robert Wessel <robertwessel2@yahoo.com> - 2015-09-28 22:03 -0500
Re: How to write this sign function in Delphi. Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-30 01:13 -0700
Re: How to write this sign function in Delphi. Bartc <bc@freeuk.com> - 2015-09-30 17:06 +0100
Re: How to write this sign function in Delphi. Richard Heathfield <rjh@cpax.org.uk> - 2015-09-30 17:26 +0100
Re: How to write this sign function in Delphi. Keith Thompson <kst-u@mib.org> - 2015-09-30 13:04 -0700
Re: How to write this sign function in Delphi. glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-09-28 09:12 +0000
Re: How to write this sign function in Delphi. David Brown <david.brown@hesbynett.no> - 2015-09-28 12:28 +0200
Re: How to write this sign function in Delphi. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-09-28 20:44 +0100
Re: How to write this sign function in Delphi. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-10-01 01:39 -0700
Re: How to write this sign function in Delphi. Keith Thompson <kst-u@mib.org> - 2015-10-01 08:55 -0700
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-01 09:02 -0700
Re: How to write this sign function in Delphi. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-10-01 14:55 -0700
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-01 16:48 -0700
Re: How to write this sign function in Delphi. raltbos@xs4all.nl (Richard Bos) - 2015-10-02 11:46 +0000
Re: How to write this sign function in Delphi. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-10-06 00:15 -0700
Re: How to write this sign function in Delphi. Les Cargill <lcargill99@comcast.com> - 2015-10-06 02:43 -0500
Re: How to write this sign function in Delphi. David Brown <david.brown@hesbynett.no> - 2015-10-06 10:13 +0200
Re: How to write this sign function in Delphi. Les Cargill <lcargill99@comcast.com> - 2015-10-06 19:14 -0500
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-06 21:36 -0700
Re: How to write this sign function in Delphi. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-06 09:25 +0100
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-06 09:28 -0700
Re: How to write this sign function in Delphi. Keith Thompson <kst-u@mib.org> - 2015-10-06 13:11 -0700
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-06 13:56 -0700
Re: How to write this sign function in Delphi. glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-07 00:25 +0000
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-06 09:44 -0700
Re: How to write this sign function in Delphi. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-10-06 10:08 -0700
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-06 12:00 -0700
Re: How to write this sign function in Delphi. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-10-07 01:58 -0700
Re: How to write this sign function in Delphi. Richard Heathfield <rjh@cpax.org.uk> - 2015-10-07 10:12 +0100
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-08 00:40 -0700
Re: How to write this sign function in Delphi. Philip Lantz <prl@canterey.us> - 2015-10-03 12:29 -0700
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-03 13:20 -0700
Re: How to write this sign function in Delphi. Philip Lantz <prl@canterey.us> - 2015-10-03 12:33 -0700
Re: How to write this sign function in Delphi. James Kuyper <jameskuyper@verizon.net> - 2015-10-03 17:02 -0400
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-03 15:04 -0700
Re: How to write this sign function in Delphi. glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-04 05:12 +0000
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-04 12:58 -0700
Re: How to write this sign function in Delphi. Philip Lantz <prl@canterey.us> - 2015-10-03 12:37 -0700
Re: How to write this sign function in Delphi. James Kuyper <jameskuyper@verizon.net> - 2015-10-03 16:21 -0400
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-03 16:05 -0700
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-10-03 14:02 -0700
Re: How to write this sign function in Delphi. supercat@casperkitty.com - 2015-09-24 09:39 -0700
Re: How to write this sign function in Delphi. raltbos@xs4all.nl (Richard Bos) - 2015-09-27 16:26 +0000
Re: How to write this sign function in Delphi. M Philbrook <jamie_ka1lpa@charter.net> - 2015-09-21 22:06 -0400
Re: How to write this sign function in Delphi. James Kuyper <jameskuyper@verizon.net> - 2015-09-22 10:17 -0400
Re: How to write this sign function in Delphi. M Philbrook <jamie_ka1lpa@charter.net> - 2015-09-22 19:48 -0400
Re: How to write this sign function in Delphi. Noob <root@127.0.0.1> - 2015-09-23 13:15 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-21 21:25 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-21 21:54 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-21 22:02 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-21 21:50 +0200
Re: How to write this sign function in Delphi. M Philbrook <jamie_ka1lpa@charter.net> - 2015-09-21 18:08 -0400
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-22 08:31 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-22 10:18 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-22 10:50 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-22 11:00 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-22 11:07 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-22 11:20 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-22 11:15 +0200
Re: How to write this sign function in Delphi. "Skybuck Flying" <skybuck2000@hotmail.com> - 2015-09-22 11:23 +0200
Page 6 of 8 — ← Prev page 1 2 3 4 5 [6] 7 8 Next page →
| From | Les Cargill <lcargill99@comcast.com> |
|---|---|
| Date | 2015-10-06 02:43 -0500 |
| Message-ID | <muvton$vdt$1@dont-email.me> |
| In reply to | #72028 |
Malcolm McLean wrote: > On Friday, October 2, 2015 at 12:46:44 PM UTC+1, Richard Bos wrote: >> Malcolm McLean <malcolm.mclean5@btinternet.com> wrote: >> >>> But, to give a real example, a bit of code I'm working on at the moment >>> uses a pathfinding algorithm to trace a path through an image intended >>> for human viewing. It then scores the path based on a penalty for >>> each cell, the numbers not going above about 50. >>> Now, pretty clearly, images intended for human viewing and manipulated >>> on desktop systems don't go above 4000 pixels a side. And any path >>> longer than about five times the straight line distance is going to >>> be thrown out by other logic. So the highest value we can get is 4000 >>> * 5 * 50, or a million, and that's a generous estimate. 32 bits is >>> perfectly safe. >> >> What happens if your input file has got corrupted? Or if someone >> accidentally feeds the program the wrong file entirely? >> > Garbage in, garbage out. > You could construct an image that is one pixel high by millions of > pixels wide, and of course the path finding algorithm would sum > the penalties of each pixel, until eventually a 32 bit int > overflowed. It would then decide that the single possible path > was the cheapest one, and report it. If you allowed 2 pixels > wide, you'd probably get the wrong path, as you've then got several > alternative paths which would be pruned badly as the total penalties > flowed over and became negative. > A really good compiler would of course detect arithmetical overflow > and terminate the function, but that's rare. > I would not consider that a good compiler. Sometimes you really do want to operate on additive rings from say, 0...0xFFFF. -- Les Cargill
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2015-10-06 10:13 +0200 |
| Message-ID | <muvvni$5g3$2@dont-email.me> |
| In reply to | #72030 |
On 06/10/15 09:43, Les Cargill wrote: > I would not consider that a good compiler. Sometimes > you really do want to operate on additive rings from say, 0...0xFFFF. > When you want an additive ring like that, why not just write it in the C code? sum = (sum + *p++) & 0xffff; (or whatever). That makes it clear what you want, and since most targets are quite happy with doing that in a single hardware instruction, the compiler will optimise code appropriately.
[toc] | [prev] | [next] | [standalone]
| From | Les Cargill <lcargill99@comcast.com> |
|---|---|
| Date | 2015-10-06 19:14 -0500 |
| Message-ID | <mv1nri$vb$1@dont-email.me> |
| In reply to | #72031 |
David Brown wrote: > On 06/10/15 09:43, Les Cargill wrote: > >> I would not consider that a good compiler. Sometimes >> you really do want to operate on additive rings from say, 0...0xFFFF. >> > > When you want an additive ring like that, why not just write it in the C > code? > > sum = (sum + *p++) & 0xffff; > > (or whatever). > I'm thinking that unsigned saturation just silently going back to zero is simply the most commonly expected behavior. How it is better if it, say, throws an exception*? As the hoary old saying goes, now you have two problems :) *Malcolm said "terminates the function", which leaves a lot of room for imagining things. > That makes it clear what you want, and since most targets are quite > happy with doing that in a single hardware instruction, the compiler > will optimise code appropriately. > > I probably would anyway, just for clarity. -- Les Cargill
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-10-06 21:36 -0700 |
| Message-ID | <2fa423ce-0c48-4915-8668-e77c5d97aa20@googlegroups.com> |
| In reply to | #72101 |
On Tuesday, October 6, 2015 at 7:11:36 PM UTC-5, Les Cargill wrote: > How it is better if it, say, throws an exception*? As the hoary old > saying goes, now you have two problems :) A good language should provide means of performing "unchecked" arithmetic on algebraic rings, and *also* provide means of performing "checked" arithmetic which would allow a program to know if overflow occurred. While C# uses exceptions for that purpose, I would suggest that for high performance code it would be more helpful to have something with somewhat looser semantics. Trying to check after every operation whether the result is in bounds, and requiring that code trap as soon as a computation goes out of bounds, is expensive. It also severely limits the ability of a compiler to rearrange the order in which things are evaluated. In cases where it is important that programs not output seemingly-valid-but- wrong data, overflow trapping is highly desirable; supporting it efficiently, however, will require a means by which programs can indicate what semantic guarantees they actually require with regard to what code will or will not execute before performing a "goto" to a trap handler (which would need to be in the same function). Allowing for the possibility that, in the absence of specific directives to the contrary, a compiler might run an unspecified amount of code before jumping to the overflow handler could in many cases greatly reduce the overhead of overflow trapping--sometimes to almost nothing--but there would be no way to achieve anything near that performance in standard C as it exists today.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-10-06 09:25 +0100 |
| Message-ID | <877fn0bdyr.fsf@bsb.me.uk> |
| In reply to | #72030 |
Les Cargill <lcargill99@comcast.com> writes: > Malcolm McLean wrote: <snip a n example that uses integer arithmetic> >> A really good compiler would of course detect arithmetical overflow >> and terminate the function, but that's rare. >> > > I would not consider that a good compiler. Sometimes > you really do want to operate on additive rings from say, 0...0xFFFF. But you don't need a good compiler for that. Any conforming compiler will do -- just use uint_fast32_t and mask once at the end. What's missing from C is a simple way to say "I want the correct arithmetic result or nothing". You can program it (which is a bit messy) and use conditional compilation where you know your hardware will help out, or you can use a compiler that will do it for you. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-10-06 09:28 -0700 |
| Message-ID | <d818b82e-d595-41e5-b4b9-e1de55cd8e01@googlegroups.com> |
| In reply to | #72032 |
On Tuesday, October 6, 2015 at 3:26:05 AM UTC-5, Ben Bacarisse wrote:
> But you don't need a good compiler for that. Any conforming compiler
> will do -- just use uint_fast32_t and mask once at the end.
If the C Standard were to mandate (as I think it should) that in cases where
the result of an additive, multiplicative, bitwise, or left-shifting
arithmetic operator is cast or coerced to an unsigned type smaller than "int",
its operands shall be likewise coerced and operations must behave as though
performed on that smaller type, such a change would not affect any behaviors
defined by the Standard, and I doubt they would affect any behaviors which
are defined in any compiler, but they would allow code like:
uint32_t x,y;
x *= y;
to regard uint32_t as an algebraic ring. At present, however, in order for
such code to be safe it is necessary to write the second statement as:
x *= 1u*y;
and eliminating compiler warnings would likely require it to be written as
x *= (uint32_t)(1u*y);
Since forgetting the second set of parentheses may allow a compiler where
"int" is e.g. 64 bits to generate bogus code without issuing a diagnostic
in situations where performing the multiplication on integers rather than
ring members would yield a number greater than 9223372036854775807, I
would suggest that safety benefits of those rules would greatly outweigh
the loss of optimization opportunities (since most of the "optimization"
opportunities that would be eliminated by that rule would be cases where
the the Standard would allow an optimizer would replace code that worked
with "more efficient" code that didn't).
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-10-06 13:11 -0700 |
| Message-ID | <ln7fmzlpu8.fsf@kst-u.example.com> |
| In reply to | #72059 |
supercat@casperkitty.com writes:
> On Tuesday, October 6, 2015 at 3:26:05 AM UTC-5, Ben Bacarisse wrote:
>> But you don't need a good compiler for that. Any conforming compiler
>> will do -- just use uint_fast32_t and mask once at the end.
>
> If the C Standard were to mandate (as I think it should) that in cases where
> the result of an additive, multiplicative, bitwise, or left-shifting
> arithmetic operator is cast or coerced to an unsigned type smaller than "int",
> its operands shall be likewise coerced and operations must behave as though
> performed on that smaller type, such a change would not affect any behaviors
> defined by the Standard, and I doubt they would affect any behaviors which
> are defined in any compiler, but they would allow code like:
>
> uint32_t x,y;
> x *= y;
>
> to regard uint32_t as an algebraic ring. At present, however, in order for
> such code to be safe it is necessary to write the second statement as:
>
> x *= 1u*y;
>
> and eliminating compiler warnings would likely require it to be written as
>
> x *= (uint32_t)(1u*y);
[...]
Let me try to summarize the underlying problem you're talking about.
C has a collection of predefined integer types: char, short, int, long,
and long long (plus the corresponding unsigned types, with a group of 3
character types).
Each arithmetic operation takes one or two operands of a type and yields
a result of the same type. (<< and >> don't *quite* fit into that
model; I'll ignore that for now.) No arithmetic operations are defined
for types narrower than int and unsigned int; operands of such type are
always promoted, either to int or to unsigned int.
short s0, s1, s2;
/* ... */
s0 = s1 + s2; /* promotes to int, adds, converts back to short */
int i0, i1, i2;
/* ... */
i0 = i1 + i2; /* The addition is performed directly on int */
If a CPU happens to have a narrow addition operator, a compiler
and use it only if the result is the same that would be given under
the promotion rules.
This means that the predefined integer types are divided into two
groups: types narrower than int, which must be promoted before you
can perform arithmetic operations, and types at least as wide as int,
on which operations can be performed directly. As long as you're
aware of the rules, and *as long as you're using the predefined
types*, this isn't much of a problem.
Then C99 added the intN_t and uintN_t types, each typically defined
as a typedef for one of the predefined types. We still have the
distinction between narrow and wide types, but now we don't know
where the dividing line is. It could be between int8_t and int16_t,
between int16_t and int32_t, or between int32_t and int64_t.
In pre-ANSI C, some compilers used unsigned preserving rules for
integer promotion, and others used value preserving rules. The 1989
ANSI standard mandated value preserving rules, which is why a 16-bit
unsigned short can promote to a 32-bit signed int rather than to
a 32-bit unsigned int. This is discussed in the C99 Rationale,
section 6.3.1.1.
http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf
I wonder if unsigned preserving rules would have avoided this issue,
or whether it would have caused more problems. In any case, it's too
late to reverse that decision; it would break too much existing code.
I don't know of a good solution.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-10-06 13:56 -0700 |
| Message-ID | <054eae0f-20f8-4b4c-b23a-49f9d7928c73@googlegroups.com> |
| In reply to | #72083 |
On Tuesday, October 6, 2015 at 3:11:49 PM UTC-5, Keith Thompson wrote:
> In pre-ANSI C, some compilers used unsigned preserving rules for
> integer promotion, and others used value preserving rules. The 1989
> ANSI standard mandated value preserving rules, which is why a 16-bit
> unsigned short can promote to a 32-bit signed int rather than to
> a 32-bit unsigned int. This is discussed in the C99 Rationale,
> section 6.3.1.1.
>
> http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf
>
> I wonder if unsigned preserving rules would have avoided this issue,
> or whether it would have caused more problems. In any case, it's too
> late to reverse that decision; it would break too much existing code.
>
> I don't know of a good solution.
The best solution I can envision which would avoid "chicken-and-egg"
problems would be for the Standard to define some new families of types
including uwrapN_t and unumN_t, with the semantics that when uwrapN_t is
defined, values of that type must promote in essentially the same
situations as would have occurred on systems where "int" was N bits,
and when unumN_t is defined, values of that type must in all cases be
promoted to a signed type which is at least 8 bits larger.
If programmers switched to using uwrapN_t and unumN_t whenever the
behavior mattered, all that would happen for existing compilers to
support programs using those types *in cases where the code would
run correctly using the uintN_t types* would be for compilers to add
the appropriate types to their stdint.h as aliases for uint32_t types,
based upon the size of "int":
16-bit int: unum8_t, uwrap16_t, uwrap32_t, uwrap64_t
32-bit int: unum8_t, unum16_t, uwrap32_t, uwrap64_t
64-bit int: unum8_t, unum16_t, unum32_t, uwrap64_t
While it may be necessary, before adding such types to the language, to
clarify exactly what the rules should be for the promotion of wrapN_t
types which are smaller than int. I would suggest that since there
cannot be any existing code which uses such types, but code written for
systems with a smaller "int" type may get ported to systems with a
larger "int" type, it may be best to define rules such that the more
potentially-ambiguous cases would be considered ill-formed (thus
requiring that a programmer specify what was intended more clearly).
While I'm open to suggestions, I would suggest that operations between
a uwrapN_t smaller than "int" and a signed type which is no bigger
should yield uwrapN_t; operations with a signed type which is larger
should yield a compilation error unless the signed-type value is an
integer constant which would be within range for either the uwrapN_t
or intN_t type, in which case the compiler should silently yield a
result of type uwrapN_t.
IMHO, if new construct would have no meaning under an older version
of the Standard, it is better to have a compiler squawk in cases whose
meaning may be ambiguous than have it generate code whose meaning would
be likely not to match programmer intention. Having to deal with compiler
squawks by adding typecasts to clarify what was intended is apt to be
much less of a problem than having to deal with code which behaves in
unexpected fashion after porting to a machine with a larger "int" size.
Do you see any downsides to the "uwrapN_t" and "unumN_t" types as defined?
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2015-10-07 00:25 +0000 |
| Message-ID | <mv1oqa$vv$1@speranza.aioe.org> |
| In reply to | #72083 |
Keith Thompson <kst-u@mib.org> wrote: > supercat@casperkitty.com writes: (snip) >> If the C Standard were to mandate (as I think it should) that >> in cases where the result of an additive, multiplicative, >> bitwise, or left-shifting arithmetic operator is cast or >> coerced to an unsigned type smaller than "int", its operands >> shall be likewise coerced and operations must behave as though >> performed on that smaller type, such a change would not affect >> any behaviors defined by the Standard, and I doubt they would >> affect any behaviors which are defined in any compiler, >> but they would allow code like: (snip) >> and eliminating compiler warnings would likely require it to be written as >> x *= (uint32_t)(1u*y); > [...] > Let me try to summarize the underlying problem you're talking about. > C has a collection of predefined integer types: char, short, int, long, > and long long (plus the corresponding unsigned types, with a group of 3 > character types). > Each arithmetic operation takes one or two operands of a type and yields > a result of the same type. (<< and >> don't *quite* fit into that > model; I'll ignore that for now.) No arithmetic operations are defined > for types narrower than int and unsigned int; operands of such type are > always promoted, either to int or to unsigned int. As well as I know it, Fortran does not have the promotion rule. I suspect that promotion to int more often than not causes programs to work, even when they otherwise might not have. That is, when the author forgot about promotion. > short s0, s1, s2; > /* ... */ > s0 = s1 + s2; /* promotes to int, adds, converts back to short */ > int i0, i1, i2; > /* ... */ > i0 = i1 + i2; /* The addition is performed directly on int */ > If a CPU happens to have a narrow addition operator, a compiler > and use it only if the result is the same that would be given under > the promotion rules. And note that expression evalution is not dependent on the type of variable it might be assigned to. But yes, if the compiler figures out that the result is the same, it can optimize it. > This means that the predefined integer types are divided into two > groups: types narrower than int, which must be promoted before you > can perform arithmetic operations, and types at least as wide as int, > on which operations can be performed directly. As long as you're > aware of the rules, and *as long as you're using the predefined > types*, this isn't much of a problem. > Then C99 added the intN_t and uintN_t types, each typically defined > as a typedef for one of the predefined types. We still have the > distinction between narrow and wide types, but now we don't know > where the dividing line is. It could be between int8_t and int16_t, > between int16_t and int32_t, or between int32_t and int64_t. (snip on unsigned preserving and value preserving) -- glen
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-10-06 09:44 -0700 |
| Message-ID | <a77b9946-f248-4147-a205-b9c2fb4dbef9@googlegroups.com> |
| In reply to | #72032 |
On Tuesday, October 6, 2015 at 3:26:05 AM UTC-5, Ben Bacarisse wrote:
> What's missing from C is a simple way to say "I want the correct
> arithmetic result or nothing". You can program it (which is a bit
> messy) and use conditional compilation where you know your hardware will
> help out, or you can use a compiler that will do it for you.
IMHO, a good language should have semantics for both "I need either the
correct arithmetic result or a standard-defined means of knowing that I
don't have it" and also "I need the correct arithmetic result if it is
computable with the specified types, else value which, while weakly
defined, will uphold certain semantic guarantees" [I would suggest that
multiple level of semantic guarantees should be offered. The tightest,
which systems with two's-complement math should offer, would always
perform a two's-complement reduction; other guarantees may arbitrarily
decide to perform such a reduction or do various other things. If code
were to request an option which would mandate that storing any arithmetic
result into a variable must yield a number which is congruent to the
arithmetically-correct value mod the integer size, and may or may not fit
within that variable's specified type, but must not spontaneously change,
then given:
void foo(int x)
{
if (x < 0) return;
x++;
if (x > 1000) printf("Too big");
if (x < 0) printf("Negative");
}
passing a value of INT_MAX to "foo" would be required to cause it to output
exactly one of "Negative" or "Too big", but a compiler could arbitrarily
output one or the other. If a compiler can't figure out any way to honor
those requirements other than by using two's-complement reduction, then the
compiler would have to do that. On the other hand, a compiler that could
figure out that using an unsigned comparison for the second "if" would let
it meet requirements without having to use the third "if" could make the
code more efficient while still upholding the requirement that "x" behave
consistently.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2015-10-06 10:08 -0700 |
| Message-ID | <364f09b6-ef87-4e44-989e-6ccd9de9f9ca@googlegroups.com> |
| In reply to | #72062 |
On Tuesday, October 6, 2015 at 5:45:07 PM UTC+1, supe...@casperkitty.com wrote: > On Tuesday, October 6, 2015 at 3:26:05 AM UTC-5, Ben Bacarisse wrote: > > What's missing from C is a simple way to say "I want the correct > > arithmetic result or nothing". You can program it (which is a bit > > messy) and use conditional compilation where you know your hardware will > > help out, or you can use a compiler that will do it for you. > > IMHO, a good language should have semantics for both "I need either the > correct arithmetic result or a standard-defined means of knowing that I > don't have it" and also "I need the correct arithmetic result if it is > computable with the specified types, else value which, while weakly > defined, will uphold certain semantic guarantees" > There are two common situations. One is that you need the right result, if you don't have it, you must execute emergency error handling code, which by default will be to terminate the program with an error message. The other is that the wrong result is better than no result at all. (that sounds cynical, but in a video game, for example, if the baddy executes attack pattern B when the logic says he should be doing attack pattern A, that's far better than the game terminating with a blue screen and an "arithmetic overflow in function _clrx_decide_ attack_pattern-q@*2b " message). But there's seldom much point in asking for "the wrong result but make sure it's modulus 65536 the correct result when interpreted as an unsigned number".
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-10-06 12:00 -0700 |
| Message-ID | <c0059fcc-223f-4d5e-8a33-ac36ac58d6e1@googlegroups.com> |
| In reply to | #72065 |
On Tuesday, October 6, 2015 at 12:08:49 PM UTC-5, Malcolm McLean wrote:
> But there's seldom much point in asking for "the wrong result but
> make sure it's modulus 65536 the correct result when interpreted as
> an unsigned number".
In most cases, systems are going to naturally yield such a result, so the
guarantee doesn't really cost much. On the other hand, suppose one is
porting the following code from a 16-bit system to the 32-bit ARM:
uint16_t x,y; ...
x*=y;
I'd say there's a lot of usefulness in requiring that (x*y) yield a result
which is congruent to the arithmetically-correct value mod 65536. While
rules which would guarantee correct modulo behavior only in certain cases
like the above might be just as good as rules which require such behavior
always, I don't know of any platforms where honoring the more general rule
would be more expensive than honoring all of the discrete cases where the
mod behavior is important.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2015-10-07 01:58 -0700 |
| Message-ID | <3ecb9e69-348e-4526-a804-be0bb44ffd40@googlegroups.com> |
| In reply to | #72079 |
On Tuesday, October 6, 2015 at 8:00:44 PM UTC+1, supe...@casperkitty.com wrote: > On Tuesday, October 6, 2015 at 12:08:49 PM UTC-5, Malcolm McLean wrote: > > But there's seldom much point in asking for "the wrong result but > > make sure it's modulus 65536 the correct result when interpreted as > > an unsigned number". > > In most cases, systems are going to naturally yield such a result, so the > guarantee doesn't really cost much. On the other hand, suppose one is > porting the following code from a 16-bit system to the 32-bit ARM: > > uint16_t x,y; ... > x*=y; > > I'd say there's a lot of usefulness in requiring that (x*y) yield a result > which is congruent to the arithmetically-correct value mod 65536. While > rules which would guarantee correct modulo behavior only in certain cases > like the above might be just as good as rules which require such behavior > always, I don't know of any platforms where honoring the more general rule > would be more expensive than honoring all of the discrete cases where the > mod behavior is important. > I believe that is required. Remove the u and the behaviour is undefined. Most people, naturally enough, assume that an unsigned integer is meant for a value with is naturally unsigned, such as the number of employees in a company. Really, I'd suggest, unsigned values should be reserved for "values which are not really integers". An example would be a collection of flags. You might often want to overflow such values. Your code fragment isn't really full enough, however. It's impossible to say whether the expression x *= y should trap or return a modulus on overflow, until we know what x and y are supposed to represent.
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-10-07 10:12 +0100 |
| Message-ID | <mv2nhr$ogu$1@dont-email.me> |
| In reply to | #72121 |
On 07/10/15 09:58, Malcolm McLean wrote:
<snip>
> Most people, naturally enough, assume that an unsigned integer is meant
> for a value with is naturally unsigned, such as the number of employees
> in a company.
Sizes and counts, but obviously not money, temperature, co-ordinates...
> Really, I'd suggest, unsigned values should be reserved
> for "values which are not really integers".
Are you suggesting that the number of employees in a company is not
really an integer? :-) I guess what you're really saying is that you
would use a signed integer for that, even though the number of employees
in a company cannot be negative. I'd be curious to know why.
> An example would be a collection
> of flags. You might often want to overflow such values.
Firstly, you can't overflow unsigned integers. It's simply not possible
in C.
Secondly, I can't think of any reason at all why you might want to
overflow a collection of flags. But unsigned integers are useful for all
kinds of things. Consider Chris Torek's hash (the one he says isn't
his), which we might write as:
unsigned long hash(const unsigned char *s)
{
unsigned long h = 0;
for( ; *s; ++s)
{
h *= 33; h += *s;
}
return h;
}
If h's value is "not really an integer", what would you call it?
>
> Your code fragment isn't really full enough, however.
> It's impossible to say whether the expression x *= y should trap or
> return a modulus on overflow, until we know what x and y are supposed
> to represent.
Hence the importance of good name choices.
--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-10-08 00:40 -0700 |
| Message-ID | <7ae3ebeb-24cc-41c1-88c4-82d852fb414d@googlegroups.com> |
| In reply to | #72123 |
On Wednesday, October 7, 2015 at 4:12:32 AM UTC-5, Richard Heathfield wrote: > Are you suggesting that the number of employees in a company is not > really an integer? :-) I guess what you're really saying is that you > would use a signed integer for that, even though the number of employees > in a company cannot be negative. I'd be curious to know why. Among other things, because the difference between two counts should be a signed value, but the difference between two unsigned integers will be an unsigned integer of the same size unless both are smaller than "int". > unsigned long hash(const unsigned char *s) > If h's value is "not really an integer", what would you call it? On a system were "int" is 16 bits, I would regard values of type uint16_t as members of the algebraic ring of integers congruent mod 65536. There is a 1:1 equivalence between members of that ring and integers in the range 0 to 65535, but that doesn't mean the ring members are integers. Each ring member is in fact the set of all integers which are congruent to each other mod 65536. Adding any integer which is congruent to x mod 65536, to any integer which is congruent to y mod 65536, will yield an integer which is congruent to (x+y) mod 65536. There is, however, a way in which C's unsigned types fail to act like members of algebraic ring--algebraic ring members should never implicitly promote to anything other than a *smaller* ring type. Given a set of things which is congruent to x mod 65536, one can readily determine the set of things which will be congruent to x mod 256, but not the set of things which will be congruent to x mod 4294967296. Likewise, if one has a set of things that are congruent mod 65536 and one subtracts a discrete number from it, the result will still be a member of the set of things congruent mod 65536. > > Your code fragment isn't really full enough, however. > > It's impossible to say whether the expression x *= y should trap or > > return a modulus on overflow, until we know what x and y are supposed > > to represent. > > Hence the importance of good name choices. IMHO, C would be greatly improved by the addition of fixed-sized unsigned types which are specified to behave as members of the aformenetioned algebraic rings (i.e. "wrap"), independent of the size of "int", and separate unsigned types which are specified to always promote to the next larger signed type when used in calculations (used for numbers which are naturally positive, but whose differences might be negative).
[toc] | [prev] | [next] | [standalone]
| From | Philip Lantz <prl@canterey.us> |
|---|---|
| Date | 2015-10-03 12:29 -0700 |
| Message-ID | <MPG.3079cc7437a4853f6c@news.eternal-september.org> |
| In reply to | #71159 |
James Kuyper wrote: > Jens Thoms Toerring wrote: > > supercat@casperkitty.com wrote: > >> // Assume "hash_power" is a uint32_t > >> 2a. hash_power *= hash_power; > >> 2b. hash_power *= 1u*hash_power; > > > > No idea what you want to check for here. Of course. squaring > > the value of a uint32_t may overflow. Is the question what's > > the result on an overflow causes by a multiplication? > > In principle, because of the usual arithmetic conversions, the detailed > behavior of 2b depends upon whether or not UINT_MAX < UINT32_MAX. > However, the final result is the same as 2a, either way. So I'm not sure > what his point is. I think he's concerned about the case where INT_MAX > UINT32_MAX, in which case the multiplication will be done as a signed multiplication, and could therefore overflow, causing undefined behavior.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-10-03 13:20 -0700 |
| Message-ID | <588382cf-1e6a-48c9-bfef-921108838214@googlegroups.com> |
| In reply to | #71710 |
On Saturday, October 3, 2015 at 2:29:45 PM UTC-5, Philip Lantz wrote: > I think he's concerned about the case where INT_MAX > UINT32_MAX, in > which case the multiplication will be done as a signed multiplication, > and could therefore overflow, causing undefined behavior. A common real-world problem scenario is implementations where "int" is 64 bits, in which case the product of two "uint32_t" values could easily overflow. Since most platforms generally have power-of-two integer sizes without padding, promotion to signed is generally harmless in most other cases. It would, however, be legitimate [albeit very weird] for a system to define unsigned char = 32 bits int = 32 value bits, one sign bit, and 31 padding bits unsigned int = 32 value bits and 32 padding bits in which case the system could legitimately define uint32_t (as an alias for unsigned char), and UINT_MAX would equal 4294967295, but even incrementing a value of type "uint32_t" could yield Undefined Behavior (since 4294967296 is greater than INT_MAX).
[toc] | [prev] | [next] | [standalone]
| From | Philip Lantz <prl@canterey.us> |
|---|---|
| Date | 2015-10-03 12:33 -0700 |
| Message-ID | <MPG.3079cd73b7768d3e6d@news.eternal-september.org> |
| In reply to | #71159 |
James Kuyper wrote: > Jens Thoms Toerring wrote: > > supercat@casperkitty.com wrote: > >> 4a. int32_t x = (int32_t)(some_uint32_value); > > > > If the intention is that 'x' afterwards has the same value as > > 'some_uint32_value' then this is doomed to fail for some uint32_t > > values since the standard requires that all positive integers of > > a signed type fit into the corresponding unsigned type but, of > > course, not also the other way round. What you are guaranteed > > (I think) is that 'x' will contain a value that has the same bit > > representation as 'some_uint32_value' (whatever that may buy you;-) > > That's not guaranteed by the standard, which is his point. > > >> 4b. int32_t x = (some_uint32_value & 0x80000000) ? > >> (int32_t)(some_uint32_t value-0x80000000)-0x40000000-0x40000000 : > >> (int32_t)some_uint32_t value; > > > > No idea what you want to achieve here. > > According to the standard, the behavior of 4a is undefined when > some_uint32_max > INT32_MAX. However, on most modern systems, it > actually behaves in a way that is well understood and widely known. This is true, but some compilers might then "optimize out" a following check for x < 0. Supercat (and I) would like to be able to take advantage of the fact that "it actually behaves in a way that is well understood and widely known", without opening ourselves up to the compiler doing something silly with some other part of the code.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-10-03 17:02 -0400 |
| Message-ID | <mupfm9$31k$1@dont-email.me> |
| In reply to | #71713 |
On 10/03/2015 03:33 PM, Philip Lantz wrote: > James Kuyper wrote: >> Jens Thoms Toerring wrote: >>> supercat@casperkitty.com wrote: >>>> 4a. int32_t x = (int32_t)(some_uint32_value); >>> >>> If the intention is that 'x' afterwards has the same value as >>> 'some_uint32_value' then this is doomed to fail for some uint32_t >>> values since the standard requires that all positive integers of >>> a signed type fit into the corresponding unsigned type but, of >>> course, not also the other way round. What you are guaranteed >>> (I think) is that 'x' will contain a value that has the same bit >>> representation as 'some_uint32_value' (whatever that may buy you;-) >> >> That's not guaranteed by the standard, which is his point. >> >>>> 4b. int32_t x = (some_uint32_value & 0x80000000) ? >>>> (int32_t)(some_uint32_t value-0x80000000)-0x40000000-0x40000000 : >>>> (int32_t)some_uint32_t value; >>> >>> No idea what you want to achieve here. >> >> According to the standard, the behavior of 4a is undefined when >> some_uint32_max > INT32_MAX. However, on most modern systems, it >> actually behaves in a way that is well understood and widely known. > > This is true, but some compilers might then "optimize out" a following > check for x < 0. Supercat (and I) would like to be able to take > advantage of the fact that "it actually behaves in a way that is well > understood and widely known", without opening ourselves up to the > compiler doing something silly with some other part of the code. But, setting yourself up for the "compiler doing something silly" is a normal consequence of making assumptions, like "It will behave in the well understood and widely known fashion", when the standard does not actually required it to behave that way. Depending upon the target platforms for your code, that assumption might be entirely reasonable. If that assumption is one you're willing to make, why aren't you equally willing to make the assumption that it won't perform that optimization, even though it's entitled to do so? The second assumption is probably correct under almost precisely the same conditions that the first one is. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-10-03 15:04 -0700 |
| Message-ID | <73603ffd-283f-4b87-89b8-84b7d760e807@googlegroups.com> |
| In reply to | #71734 |
On Saturday, October 3, 2015 at 4:03:10 PM UTC-5, James Kuyper wrote: > But, setting yourself up for the "compiler doing something silly" is a > normal consequence of making assumptions, like "It will behave in the > well understood and widely known fashion", when the standard does not > actually required it to behave that way. Depending upon the target > platforms for your code, that assumption might be entirely reasonable. > If that assumption is one you're willing to make, why aren't you equally > willing to make the assumption that it won't perform that optimization, > even though it's entitled to do so? The second assumption is probably > correct under almost precisely the same conditions that the first one is. I think a fundamental problem with the C Standard from the get-go is that even though the Standard was written *after* the language was already being used to write a lot of production code, the authors of the Standard did not want to recognize behavioral guarantees which existing code was relying upon, but which could efficiently not be upheld on all platforms. While I appreciate that there is value in being able to have a platform which cannot uphold certain behavioral guarantees that some code might rely upon, nonetheless be able to run code *which does not require those guarantees*, the failure to even recognize such guarantees meant that the language described by the C89 specification was significantly weaker than the C language that people were using before the C89 spec was published. Originally, this didn't pose much of a problem, since compilers and programmers alike both recognized that what was needed was not a compiler that did the minimum necessary to meet the spec, but rather a compiler that could process the existing base of production code in such a fashion as to meet its requirements. Unfortunately, over the years, some compiler writers have acquired an attitude that code which relies upon behavioral guarantees which were not included in the spec should be viewed as "defective", rather than recognizing that there was value in having systems which could cheaply uphold such guarantees, do so. Nothing in the C Standard would prohibit an implementation from physically bursting into flames in case of numeric overflow, and it's possible that such an implementation might be able to run code faster than would be possible if it were required not to burst into flames; someone writing a C program for such a platform should often be required to add extra code to avoid overflows at all costs, but if the slowdown caused by that extra code might be outweighed by the faster performance made possible by easing the "don't burst into flames" requirement on the hardware (and if nobody slips up) the trade-off may be worthwhile *for code written to target that platform*. I do not think it helpful, however, to suggest that all code should be written as though it might be run on hardware that will burst into flames in case of overflow, even when owners of such hardware would be unlikely to ever have any interest in the code in question. One of the reasons that C has thrived is that people targeting platforms which could offer guarantees beyond those required by the Standard were able to make use of those guarantees. Remove the notion that compilers should try to extend to programmers the guarantees offered by the underlying platforms and what's left will be totally unsuitable for many of the purposes that C was designed for.
[toc] | [prev] | [next] | [standalone]
Page 6 of 8 — ← Prev page 1 2 3 4 5 [6] 7 8 Next page →
Back to top | Article view | comp.lang.c
csiph-web