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


Groups > comp.lang.c > #93363 > unrolled thread

Portable 16 bit binary integer write

Started byMalcolm McLean <malcolm.mclean5@btinternet.com>
First post2016-09-10 14:23 -0700
Last post2016-09-13 07:47 -0700
Articles 20 on this page of 171 — 17 participants

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


Contents

  Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-10 14:23 -0700
    Re: Portable 16 bit binary integer write Barry Schwarz <schwarzb@dqel.com> - 2016-09-10 17:11 -0700
    Re: Portable 16 bit binary integer write Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-11 07:00 -0700
    Re: Portable 16 bit binary integer write Richard Damon <Richard@Damon-Family.org> - 2016-09-13 08:41 -0400
      Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-13 06:24 -0700
        Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-13 16:19 +0200
          Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-13 10:20 -0700
            Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-13 11:07 -0700
          Re: Portable 16 bit binary integer write Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-13 20:47 -0700
            Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-14 08:24 -0700
              Re: Portable 16 bit binary integer write Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-15 12:17 -0700
            Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-15 11:27 +0200
              Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-15 09:03 -0700
                Re: Portable 16 bit binary integer write Keith Thompson <kst-u@mib.org> - 2016-09-15 11:21 -0700
                Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-15 18:39 +0200
                  Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-15 12:26 -0700
                    Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-15 23:12 +0200
                      Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-15 16:17 -0700
                        Re: Portable 16 bit binary integer write Keith Thompson <kst-u@mib.org> - 2016-09-15 18:35 -0700
                        Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-16 11:10 +0200
                          Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-16 08:43 -0700
                            Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-16 19:59 +0200
                              Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-16 13:34 -0700
                                Re: Portable 16 bit binary integer write Keith Thompson <kst-u@mib.org> - 2016-09-16 16:23 -0700
                                  Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-16 15:31 -0700
                                    Re: Portable 16 bit binary integer write Keith Thompson <kst-u@mib.org> - 2016-09-16 19:06 -0700
                                      Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-16 23:27 -0700
                                        Re: Portable 16 bit binary integer write Keith Thompson <kst-u@mib.org> - 2016-09-17 15:04 -0700
                                          Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-17 20:35 -0700
                                            Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-18 00:09 -0700
                                              Re: Portable 16 bit binary integer write Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-18 19:36 +0100
                                                Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-18 15:29 -0700
                                                  Re: Portable 16 bit binary integer write Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-19 01:20 +0100
                                            Re: Portable 16 bit binary integer write Keith Thompson <kst-u@mib.org> - 2016-09-18 09:48 -0700
                                              Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-18 19:38 +0200
                                                Re: Portable 16 bit binary integer write Keith Thompson <kst-u@mib.org> - 2016-09-18 15:33 -0700
                                                  Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-18 13:58 -0700
                                                  Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-18 14:15 -0700
                                                  Re: Portable 16 bit binary integer write BartC <bc@freeuk.com> - 2016-09-18 23:15 +0100
                                                    Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-18 15:46 -0700
                                                      Re: Portable 16 bit binary integer write Ian Collins <ian-news@hotmail.com> - 2016-09-19 17:03 +1200
                                                        Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-19 07:40 -0700
                                                          Re: Portable 16 bit binary integer write Keith Thompson <kst-u@mib.org> - 2016-09-19 10:54 -0700
                                                    Re: Portable 16 bit binary integer write Keith Thompson <kst-u@mib.org> - 2016-09-19 10:51 -0700
                                                      Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-19 22:03 +0200
                                                        Re: Portable 16 bit binary integer write Keith Thompson <kst-u@mib.org> - 2016-09-19 15:44 -0700
                                                          Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-20 09:02 +0200
                                                      Re: Portable 16 bit binary integer write BartC <bc@freeuk.com> - 2016-09-19 21:12 +0100
                                                        Re: Portable 16 bit binary integer write Keith Thompson <kst-u@mib.org> - 2016-09-19 15:58 -0700
                                                  Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-19 09:49 +0200
                                                    Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-19 02:37 -0700
                                                      Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-19 13:20 +0200
                                                        Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-19 06:22 -0700
                                                    Re: Portable 16 bit binary integer write BartC <bc@freeuk.com> - 2016-09-19 12:46 +0100
                                                      Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-19 16:20 +0200
                                                    Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-19 07:32 -0700
                                                    Re: Portable 16 bit binary integer write Keith Thompson <kst-u@mib.org> - 2016-09-19 11:26 -0700
                                                      Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-19 09:10 -0700
                                                        Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-19 09:33 -0700
                                                      Re: Portable 16 bit binary integer write Keith Thompson <kst-u@mib.org> - 2016-09-19 11:54 -0700
                                                        Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-19 22:14 +0200
                                                      Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-19 22:12 +0200
                                                        Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-19 14:32 -0700
                                                          Re: Portable 16 bit binary integer write Robert Wessel <robertwessel2@yahoo.com> - 2016-09-19 22:58 -0500
                                                          Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-20 09:45 +0200
                                                            Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-20 07:49 -0700
                                                              Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-20 19:43 +0200
                                                                Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-20 11:15 -0700
                                                        Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-19 22:36 -0700
                                                          Re: Portable 16 bit binary integer write Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-22 21:30 -0700
                                                            Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-22 23:58 -0700
                                                              Re: Portable 16 bit binary integer write Ian Collins <ian-news@hotmail.com> - 2016-09-23 19:45 +1200
                                                              Re: Portable 16 bit binary integer write Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-28 08:17 -0700
                                                                Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-28 09:59 -0700
                                                                  Re: Portable 16 bit binary integer write Ian Collins <ian-news@hotmail.com> - 2016-09-29 07:59 +1300
                                                                    Re: Portable 16 bit binary integer write Ike Naar <ike@iceland.freeshell.org> - 2016-09-28 19:26 +0000
                                                                  Re: Portable 16 bit binary integer write Keith Thompson <kst-u@mib.org> - 2016-09-28 12:37 -0700
                                                                  Re: Portable 16 bit binary integer write Tim Rentsch <txr@alumni.caltech.edu> - 2016-10-09 03:46 -0700
                                              Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-18 13:53 -0700
                                          Re: Portable 16 bit binary integer write Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-21 21:03 -0700
                                            Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-21 22:23 -0700
                                              Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-22 08:09 -0700
                                              Re: Portable 16 bit binary integer write Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-23 10:31 -0700
                                                Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-23 10:56 -0700
                                                  Re: Portable 16 bit binary integer write Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-29 08:03 -0700
                                                    Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-30 07:39 -0700
                                            Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-22 09:49 +0200
                                              Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-22 08:34 -0700
                                                Re: Portable 16 bit binary integer write BartC <bc@freeuk.com> - 2016-09-22 17:44 +0100
                                                  Re: Portable 16 bit binary integer write Melzzzzz <Melzzzzz@zzzzz.com> - 2016-09-22 17:16 +0000
                                                    Re: Portable 16 bit binary integer write BartC <bc@freeuk.com> - 2016-09-22 18:26 +0100
                                                      Re: Portable 16 bit binary integer write Melzzzzz <Melzzzzz@zzzzz.com> - 2016-09-22 17:33 +0000
                                                      Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-23 10:23 +0200
                                                        Re: Portable 16 bit binary integer write Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-23 13:43 +0100
                                                          Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-23 14:58 +0200
                                                  Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-22 18:14 -0700
                                                    Re: Portable 16 bit binary integer write luser droog <luser.droog@gmail.com> - 2016-09-22 20:28 -0700
                                                      Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-23 00:12 -0700
                                                Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-22 10:57 -0700
                                                Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-23 10:18 +0200
                                              Re: Portable 16 bit binary integer write Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-23 11:48 -0700
                                                Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-23 15:58 -0700
                                                  Re: Portable 16 bit binary integer write Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-29 08:21 -0700
                                                    Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-30 07:42 -0700
                                                Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-23 23:38 -0700
                                                  Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-24 11:42 -0700
                                                  Re: Portable 16 bit binary integer write Keith Thompson <kst-u@mib.org> - 2016-09-24 14:13 -0700
                                                    Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-24 23:03 -0700
                                                      Re: Portable 16 bit binary integer write Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-25 11:29 +0100
                                                        Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-25 14:02 -0700
                                                          Re: Portable 16 bit binary integer write Keith Thompson <kst-u@mib.org> - 2016-09-25 15:17 -0700
                                                            Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-25 16:52 -0700
                                                    Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-25 13:59 -0700
                                                      Re: Portable 16 bit binary integer write Keith Thompson <kst-u@mib.org> - 2016-09-25 15:13 -0700
                                                        Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-25 15:50 -0700
                                                  Re: Portable 16 bit binary integer write Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-28 08:13 -0700
                                                Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-24 16:06 +0200
                                                  Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-24 11:53 -0700
                                                    Re: Portable 16 bit binary integer write Keith Thompson <kst-u@mib.org> - 2016-09-24 14:23 -0700
                                                      Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-25 14:16 -0700
                                                        Re: Portable 16 bit binary integer write Keith Thompson <kst-u@mib.org> - 2016-09-25 15:18 -0700
                                                          Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-25 16:39 -0700
                                                            Re: Portable 16 bit binary integer write Keith Thompson <kst-u@mib.org> - 2016-09-25 23:33 -0700
                                                          Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-26 02:08 -0700
                                                            Re: Portable 16 bit binary integer write Richard Heathfield <rjh@cpax.org.uk> - 2016-09-26 10:25 +0100
                                                              Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-26 03:05 -0700
                                                                Re: Portable 16 bit binary integer write Richard Heathfield <rjh@cpax.org.uk> - 2016-09-26 11:09 +0100
                                                              Re: Portable 16 bit binary integer write "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-09-26 09:29 -0700
                                                                Re: Portable 16 bit binary integer write Richard Heathfield <rjh@cpax.org.uk> - 2016-09-26 17:37 +0100
                                                                  Re: Portable 16 bit binary integer write "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-09-26 12:29 -0700
                                                            Re: Portable 16 bit binary integer write BartC <bc@freeuk.com> - 2016-09-26 11:12 +0100
                                                            Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-26 13:19 -0700
                                                              Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-26 18:34 -0700
                                                                Re: Portable 16 bit binary integer write Ike Naar <ike@iceland.freeshell.org> - 2016-09-27 06:43 +0000
                                                                  Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-27 00:51 -0700
                                                                Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-27 08:42 -0700
                                            Re: Portable 16 bit binary integer write Keith Thompson <kst-u@mib.org> - 2016-09-22 11:40 -0700
                                              Re: Portable 16 bit binary integer write Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-23 10:00 -0700
                                                Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-23 10:34 -0700
                                                  Re: Portable 16 bit binary integer write Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-29 08:13 -0700
                                        Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-18 00:06 +0200
                                          Re: Portable 16 bit binary integer write Keith Thompson <kst-u@mib.org> - 2016-09-17 17:32 -0700
                                            Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-18 15:57 +0200
                                          Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-17 20:46 -0700
                                            Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-18 16:08 +0200
                                              Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-18 10:03 -0700
                                      Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-17 23:59 +0200
                                        Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-17 16:49 -0700
                                          Re: Portable 16 bit binary integer write Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-18 01:19 +0100
                                            Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-18 07:16 -0700
                                            Re: Portable 16 bit binary integer write "James R. Kuyper" <jameskuyper@verizon.net> - 2016-09-18 10:19 -0400
                                              Re: Portable 16 bit binary integer write luser droog <luser.droog@gmail.com> - 2016-09-18 13:26 -0700
                                                Re: Portable 16 bit binary integer write "James R. Kuyper" <jameskuyper@verizon.net> - 2016-09-18 17:04 -0400
                                                Re: Portable 16 bit binary integer write Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-22 01:21 -0700
              Re: Portable 16 bit binary integer write Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-15 12:07 -0700
                Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-16 00:32 +0200
                  Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-15 16:30 -0700
                    Re: Portable 16 bit binary integer write Keith Thompson <kst-u@mib.org> - 2016-09-15 18:35 -0700
                  Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-15 22:00 -0700
                    Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-15 22:17 -0700
                      Re: Portable 16 bit binary integer write Ian Collins <ian-news@hotmail.com> - 2016-09-16 18:12 +1200
                        Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-16 00:46 -0700
                          Re: Portable 16 bit binary integer write Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-16 10:23 +0100
                          Re: Portable 16 bit binary integer write BartC <bc@freeuk.com> - 2016-09-16 10:59 +0100
                            Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-16 04:13 -0700
                            Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-16 08:58 -0700
                              Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-16 10:16 -0700
                  Re: Portable 16 bit binary integer write Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-16 09:11 -0700
                    Re: Portable 16 bit binary integer write David Brown <david.brown@hesbynett.no> - 2016-09-16 20:14 +0200
                      Re: Portable 16 bit binary integer write Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-16 20:37 -0700
        Re: Portable 16 bit binary integer write supercat@casperkitty.com - 2016-09-13 07:47 -0700

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


#93705

FromDavid Brown <david.brown@hesbynett.no>
Date2016-09-18 00:06 +0200
Message-ID<nrkepr$ptn$1@dont-email.me>
In reply to#93679
On 17/09/16 08:27, supercat@casperkitty.com wrote:
> On Friday, September 16, 2016 at 6:59:15 PM UTC-5, Keith Thompson wrote:
>> supercat writes:
>>> The expression -5 << 3 satisfies the second criterion, but fails the first.
>>> Consequently, it invokes Undefined Behavior.
>>
>> You're absolutely right.  Looks like I failed reading comprehension
>> for the day.  My apologies.
>
> Returning to my earlier point, which seems more plausible:
>
>    1. The authors of the Standard wanted to invite even two's-complement
>       implementations to behave nonsensically when left-shifting a negative
>       value unless he programmer explicitly cast the value to "unsigned"
>       first, or...
>
>    2. The authors of the Standard thought it so obvious that quality
>       two's-complement implementations should treat left-shifts of negative
>       values as a multiplication (at least in cases where the product
>       would be representable) that there was no need to waste ink saying
>       so.
>
> Before you recognized that you'd misread the Standard, you presumably would
> have thought that a programmer would be entitled to expect that when x==-5,
> a compiler would evaluate x<<3 as -40 with no side-effects.  Does the fact
> that the Standard imposes no requirements change that?
>

It changes nothing because:

a) The compiler I use most, gcc, does exactly what you expect here.  The 
documentation of this behaviour in gcc could be clearer, but combining 
the documentation with common sense (the compiler will use the simplest 
and most efficient reasonable instruction on the target cpu), you arrive 
at this interpretation.

b) I don't shift negative numbers.  It is rare that I would even shift 
positive values in a signed type - about the only case would be if I 
wanted to multiply an integer by a power of 2 (such as -5 * (1 << 3), 
rather than -5 << 3).  The compiler will no doubt turn the 
multiplication into a shift if that is more efficient on the particular 
architecture.

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


#93708

FromKeith Thompson <kst-u@mib.org>
Date2016-09-17 17:32 -0700
Message-ID<lnintuxd27.fsf@kst-u.example.com>
In reply to#93705
David Brown <david.brown@hesbynett.no> writes:
> On 17/09/16 08:27, supercat@casperkitty.com wrote:
[...]
>> Before you recognized that you'd misread the Standard, you presumably
>> would have thought that a programmer would be entitled to expect that
>> when x==-5, a compiler would evaluate x<<3 as -40 with no
>> side-effects.  Does the fact that the Standard imposes no
>> requirements change that?
>
> It changes nothing because:
>
> a) The compiler I use most, gcc, does exactly what you expect here.
> The documentation of this behaviour in gcc could be clearer, but
> combining the documentation with common sense (the compiler will use
> the simplest and most efficient reasonable instruction on the target
> cpu), you arrive at this interpretation.

I probably wouldn't rely on that, partly because ...

> b) I don't shift negative numbers.

... but also because gcc's behavior could easily vary for different
target CPUs.  It's likely that a shift on a signed integer would
use the same instruction as a shift on an unsigned integer, which
would yield the "expected" -40 on a 2's-complement system (and AFAIK
gcc only supports 2's-complement), but there could easily be some
pitfall that I haven't thought about.

Ensuring that I only shift unsigned integers, or at least that I
never shift negative integers, is a better use of my time than
verifying that shifts of negative integers are going to "work"
the way I might expect them to.

-- 
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]


#93727

FromDavid Brown <david.brown@hesbynett.no>
Date2016-09-18 15:57 +0200
Message-ID<nrm6gv$5ua$1@dont-email.me>
In reply to#93708
On 18/09/16 02:32, Keith Thompson wrote:
> David Brown <david.brown@hesbynett.no> writes:
>> On 17/09/16 08:27, supercat@casperkitty.com wrote:
> [...]
>>> Before you recognized that you'd misread the Standard, you presumably
>>> would have thought that a programmer would be entitled to expect that
>>> when x==-5, a compiler would evaluate x<<3 as -40 with no
>>> side-effects.  Does the fact that the Standard imposes no
>>> requirements change that?
>>
>> It changes nothing because:
>>
>> a) The compiler I use most, gcc, does exactly what you expect here.
>> The documentation of this behaviour in gcc could be clearer, but
>> combining the documentation with common sense (the compiler will use
>> the simplest and most efficient reasonable instruction on the target
>> cpu), you arrive at this interpretation.
> 
> I probably wouldn't rely on that, partly because ...
> 
>> b) I don't shift negative numbers.
> 
> ... but also because gcc's behavior could easily vary for different
> target CPUs.  It's likely that a shift on a signed integer would
> use the same instruction as a shift on an unsigned integer, which
> would yield the "expected" -40 on a 2's-complement system (and AFAIK
> gcc only supports 2's-complement), but there could easily be some
> pitfall that I haven't thought about.

There could be some other effect here, but I doubt it - as you say, gcc
only supports 2's complement systems.  In all cpus that I know,
"arithmetic left shift" and "logical left shift" are the same, and will
give power-of-two multiplication until you hit overflows.

Having said that, I fully agree with your opinion below.  Even though I
think left-shift of negative numbers is something you can rely on with
gcc (and any other compiler that documents the behaviour), I still can't
see any reason to do it.

> 
> Ensuring that I only shift unsigned integers, or at least that I
> never shift negative integers, is a better use of my time than
> verifying that shifts of negative integers are going to "work"
> the way I might expect them to.
> 

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


#93722

Fromsupercat@casperkitty.com
Date2016-09-17 20:46 -0700
Message-ID<33aead9b-f354-4b8b-9aea-675b68abf9b5@googlegroups.com>
In reply to#93705
On Saturday, September 17, 2016 at 5:07:03 PM UTC-5, David Brown wrote:
> a) The compiler I use most, gcc, does exactly what you expect here.  The 
> documentation of this behaviour in gcc could be clearer, but combining 
> the documentation with common sense (the compiler will use the simplest 
> and most efficient reasonable instruction on the target cpu), you arrive 
> at this interpretation.

That logic is not applicable to gcc; it will identify constructs that will
probably work, but not those that the authors of gcc won't be more than
happy to break in the name of "optimization".

Consider something like the following:

    // Assume usmall is an unsigned type half the size of "unsigned int"
    unsigned mul(usmall x, usmall y) { return x*y; }

The authors of the Standard have indicated that one of the reasons they
chose to have short unsigned types promote as signed is that doing so
would not break code like the above on silent-wraparound two's-complement
hardware (which they observed was common to the majority of then-current
implementations).

If gcc inlines the above function, however, it may arbitrarily alter the
effect of the surrounding code.

> b) I don't shift negative numbers.  It is rare that I would even shift 
> positive values in a signed type - about the only case would be if I 
> wanted to multiply an integer by a power of 2 (such as -5 * (1 << 3), 
> rather than -5 << 3).  The compiler will no doubt turn the 
> multiplication into a shift if that is more efficient on the particular 
> architecture.

I would regard x<<y as the idiomatic means of multiplying x by 1<<y, but
without any need to worry about sizing the constant according to the size
of x.

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


#93728

FromDavid Brown <david.brown@hesbynett.no>
Date2016-09-18 16:08 +0200
Message-ID<nrm759$86g$1@dont-email.me>
In reply to#93722
On 18/09/16 05:46, supercat@casperkitty.com wrote:
> On Saturday, September 17, 2016 at 5:07:03 PM UTC-5, David Brown wrote:
>> a) The compiler I use most, gcc, does exactly what you expect here.  The 
>> documentation of this behaviour in gcc could be clearer, but combining 
>> the documentation with common sense (the compiler will use the simplest 
>> and most efficient reasonable instruction on the target cpu), you arrive 
>> at this interpretation.
> 
> That logic is not applicable to gcc; it will identify constructs that will
> probably work, but not those that the authors of gcc won't be more than
> happy to break in the name of "optimization".
> 
> Consider something like the following:
> 
>     // Assume usmall is an unsigned type half the size of "unsigned int"
>     unsigned mul(usmall x, usmall y) { return x*y; }
> 
> The authors of the Standard have indicated that one of the reasons they
> chose to have short unsigned types promote as signed is that doing so
> would not break code like the above on silent-wraparound two's-complement
> hardware (which they observed was common to the majority of then-current
> implementations).
> 

Sometimes promoting "usmall" to signed int gives the simplest, clearest
and "least surprising" results - sometimes promoting it to unsigned int
would have made more sense.  The standards committee choose to pick one
method, rather than a combination (as that would have been more
complicated), or "no promotion" (as that would have been in conflict
with older C compilers, and perhaps inconvenient to many users).  And
they picked "signed int", as the most useful choice in their opinion and
experience.

So that is the way C works.  It is not simply the way gcc works, or the
way "modern" C works - it is the way /C/ works.  Get over it, or find a
different programming language.  And for the good of all of us here,
/please/ stop dragging out this example in every second post you make.

> If gcc inlines the above function, however, it may arbitrarily alter the
> effect of the surrounding code.
> 
>> b) I don't shift negative numbers.  It is rare that I would even shift 
>> positive values in a signed type - about the only case would be if I 
>> wanted to multiply an integer by a power of 2 (such as -5 * (1 << 3), 
>> rather than -5 << 3).  The compiler will no doubt turn the 
>> multiplication into a shift if that is more efficient on the particular 
>> architecture.
> 
> I would regard x<<y as the idiomatic means of multiplying x by 1<<y, but
> without any need to worry about sizing the constant according to the size
> of x.
> 

I think the best way to multiply x by 1 << y is usually x * (1 << y).  I
don't need to "worry about the sizing of the constant according to the
size of x" - C's promotion rules handle that fine.  I might need to
write "1L << y" or "1LL << y" if /y/ is too big, but the size of x does
not matter.  And I might need to cast x to a larger size to avoid an
overflow of the whole expression, but that applies no matter how you
write it.



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


#93741

Fromsupercat@casperkitty.com
Date2016-09-18 10:03 -0700
Message-ID<5c6ca1e2-716a-4082-8284-4bde53ee32f9@googlegroups.com>
In reply to#93728
On Sunday, September 18, 2016 at 9:08:56 AM UTC-5, David Brown wrote:
> Sometimes promoting "usmall" to signed int gives the simplest, clearest
> and "least surprising" results - sometimes promoting it to unsigned int
> would have made more sense.  The standards committee choose to pick one
> method, rather than a combination (as that would have been more
> complicated), or "no promotion" (as that would have been in conflict
> with older C compilers, and perhaps inconvenient to many users).  And
> they picked "signed int", as the most useful choice in their opinion and
> experience.

It is the most useful choice in cases where there the result is used as
a signed value.  In the more frequent cases where it's used as an unsigned
int, it would almost always be more useful to process values as unsigned,
but the authors of the Standard noted that implementations were already
doing that, nothing in the Standard would prohibit them from doing so,
and I see no evidence that the authors of C89 thought that commonplace
implementations might ever stop doing so.

The C89 rationale observes that on silent-wraparound two's-complement
implementations, signed and unsigned promotion would yield identical results
unless two conditions BOTH applied:

  1. The result was outside the range of INT, and

  2. The result was converted to a larger type, used as the left operand
     of >>, or used as either operand to /, %, >, <, >=, or <=.

The Standard *allows* implementations to have different signed and unsigned
behaviors in cases where 1 applies but 2 does not; I see no reason why
the authors would have mentioned the second condition unless the authors
of the Standard thought commonplace implementations would apply it even
without a mandate.

> So that is the way C works.  It is not simply the way gcc works, or the
> way "modern" C works - it is the way /C/ works.  Get over it, or find a
> different programming language.  And for the good of all of us here,
> /please/ stop dragging out this example in every second post you make.

Do you think the authors of the Standard thought there was any likelihood
that commonplace implementations would stop behaving in the described
fashion?  Do you think the authors of the Standard were prone to mandating
that implementations do things which they would obviously do anyway?

Many C compilers work precisely as described the Standard's rationale,
100% of the time, and the vast majority work in such fashion 99.9% of
the time.  I would suggest that a quality implementation should reliably
work in such fashion 100% of the time absent a compelling reason to do
otherwise, and I would not regard a 0.1% chance of being able to find an
optimization as being a compelling reason.

> > I would regard x<<y as the idiomatic means of multiplying x by 1<<y, but
> > without any need to worry about sizing the constant according to the size
> > of x.
> > 
> 
> I think the best way to multiply x by 1 << y is usually x * (1 << y).  I
> don't need to "worry about the sizing of the constant according to the
> size of x" - C's promotion rules handle that fine.  I might need to
> write "1L << y" or "1LL << y" if /y/ is too big, but the size of x does
> not matter.  And I might need to cast x to a larger size to avoid an
> overflow of the whole expression, but that applies no matter how you
> write it.

The expression x*(1<<y) will fail if x is -1 and y is INT_BITS.  I would
also suggest that in expressions which use >> for round-to-negative-infinity
division (which is how quality two's-complement implementations treat >>,
since there is no other round-to-negative-infinity division operator),
and where all scaling is by powers of two, it is more natural to use a
mix of << and >> than to throw in the * operator as well.  If C had proper
operators for Euclidian division and modulus, I might be inclined to favor
those over >> or &, but it doesn't.

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


#93702

FromDavid Brown <david.brown@hesbynett.no>
Date2016-09-17 23:59 +0200
Message-ID<nrkec8$kut$1@dont-email.me>
In reply to#93674
On 17/09/16 04:06, Keith Thompson wrote:
> supercat@casperkitty.com writes:
>> On Friday, September 16, 2016 at 4:17:31 PM UTC-5, Keith Thompson wrote:
>>> supercat writes:
>>>> I did read the standard.  From N1570 6.5.7:
>>>>
>>>> 4 The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits
>>>>    are filled with zeros.... If E1 has a signed type and nonnegative value,
>>>>    and E1 x 2E2 is representable in the result type, then that is the
>>>>    resulting value; otherwise, the behavior is undefined.
>>>
>>> Right.  Your statement was that "shifting a negative number
>>> left is UB".  It's UB only if the result is outside the range of
>>> the signed type.  Your statement implied (certainly to me, and
>>> presumably to David) that left-shifting a negative number *always*
>>> has undefined behavior.  It doesn't.
>>
>> The language of the Standard only specifies behavior if E1 is unsigned, or
>> if *both* of the following conditions apply:
>>
>>    1. E1 is signed AND NON-NEGATIVE.
>>
>>    2. The result of multiplying E1 * 2^E2 would be representable in the
>>       result type.
>>
>> The expression -5 << 3 satisfies the second criterion, but fails the first.
>> Consequently, it invokes Undefined Behavior.
>
> You're absolutely right.  Looks like I failed reading comprehension
> for the day.  My apologies.
>

My apologies too - I made the same mistake.  (And my apologies to Keith 
too if he made his mistake by assuming I was correct.)


The silly thing about this is that when Supercat first mentioned this, 
my first thought was "it doesn't matter that left-shifting a negative 
number is undefined behaviour - you would normally stick to unsigned 
types when doing bit manipulation".  And then I dug out my C standards 
and read them to see what they said - and got it wrong.

So back to my first thought, then.  Why would one ever want to 
left-shift a negative number?

It is presumably left undefined because hardware with integer 
representation other than two's complement could not give a sensible, 
useful and efficient implementation - even making it 
implementation-defined would be an imposition for such targets.

It is a little odd that right-shift of negative numbers is 
implementation-defined rather than undefined behaviour.


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


#93714

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2016-09-17 16:49 -0700
Message-ID<72994bbd-656b-4be4-8da9-e61c4bf21643@googlegroups.com>
In reply to#93702
On Saturday, September 17, 2016 at 10:59:47 PM UTC+1, David Brown wrote:
> 
> So back to my first thought, then.  Why would one ever want to 
> left-shift a negative number?
> 
> It is presumably left undefined because hardware with integer 
> representation other than two's complement could not give a sensible, 
> useful and efficient implementation - even making it 
> implementation-defined would be an imposition for such targets.
> 
> It is a little odd that right-shift of negative numbers is 
> implementation-defined rather than undefined behaviour.
>
The temptation is to write fput16le like this

/* don't use this, broken example */
fput16le(int x)
{
  fputc(x & 0xFF, fp);
  fputc( (x >> 8) &0xFF, fp);
}

I used that code for a long time with no problems. But it's
undefined behaviour and thus technically incorrect as C code.

As Tim pointed out a while back, if you simply cast to unsigned, 
it does the right thing. Even on one's complement hardware.

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


#93719

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-09-18 01:19 +0100
Message-ID<87zin6jbzr.fsf@bsb.me.uk>
In reply to#93714
Malcolm McLean <malcolm.mclean5@btinternet.com> writes:
<snip>
> The temptation is to write fput16le like this
>
> /* don't use this, broken example */
> fput16le(int x)
> {
>   fputc(x & 0xFF, fp);
>   fputc( (x >> 8) &0xFF, fp);
> }
>
> I used that code for a long time with no problems. But it's
> undefined behaviour and thus technically incorrect as C code.

Is this another case of Malcolm-speak?  It's not undefined in the C
standard sense of the word.  (The implicit int in the declaration is
presumably not intended.)

<snip>
-- 
Ben.

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


#93729

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2016-09-18 07:16 -0700
Message-ID<931904d7-c185-4e12-9b37-23fb0552bd7b@googlegroups.com>
In reply to#93719
On Sunday, September 18, 2016 at 1:19:27 AM UTC+1, Ben Bacarisse wrote:
> Malcolm McLean <malcolm.mclean5@btinternet.com> writes:
> <snip>
> > The temptation is to write fput16le like this
> >
> > /* don't use this, broken example */
> > fput16le(int x)
> > {
> >   fputc(x & 0xFF, fp);
> >   fputc( (x >> 8) &0xFF, fp);
> > }
> >
> > I used that code for a long time with no problems. But it's
> > undefined behaviour and thus technically incorrect as C code.
> 
> Is this another case of Malcolm-speak?  It's not undefined in the C
> standard sense of the word.  (The implicit int in the declaration is
> presumably not intended.)
> 
No, it's what is called mis-speaking.

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


#93730

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2016-09-18 10:19 -0400
Message-ID<7c3a4e7a-9200-7fd7-b60e-73c5434a1a8a@verizon.net>
In reply to#93719
On 09/17/2016 08:19 PM, Ben Bacarisse wrote:
> Malcolm McLean <malcolm.mclean5@btinternet.com> writes:
> <snip>
>> The temptation is to write fput16le like this
>>
>> /* don't use this, broken example */
>> fput16le(int x)
>> {
>>   fputc(x & 0xFF, fp);
>>   fputc( (x >> 8) &0xFF, fp);
>> }
>>
>> I used that code for a long time with no problems. But it's
>> undefined behaviour and thus technically incorrect as C code.
>
> Is this another case of Malcolm-speak?  It's not undefined in the C
> standard sense of the word. ...

If x is negative, the result of the shift operation is 
implementation-defined. That's not as bad as undefined behavior, but 
it's bad enough to be a problem.

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


#93756

Fromluser droog <luser.droog@gmail.com>
Date2016-09-18 13:26 -0700
Message-ID<452fcd86-7b41-490d-b871-de543d751db7@googlegroups.com>
In reply to#93730
On Sunday, September 18, 2016 at 9:20:08 AM UTC-5, James R. Kuyper wrote:
> On 09/17/2016 08:19 PM, Ben Bacarisse wrote:
> > Malcolm McLean <malcolm.mclean5@btinternet.com> writes:
> > <snip>
> >> The temptation is to write fput16le like this
> >>
> >> /* don't use this, broken example */
> >> fput16le(int x)
> >> {
> >>   fputc(x & 0xFF, fp);
> >>   fputc( (x >> 8) &0xFF, fp);
> >> }
> >>
> >> I used that code for a long time with no problems. But it's
> >> undefined behaviour and thus technically incorrect as C code.
> >
> > Is this another case of Malcolm-speak?  It's not undefined in the C
> > standard sense of the word. ...
> 
> If x is negative, the result of the shift operation is 
> implementation-defined. That's not as bad as undefined behavior, but 
> it's bad enough to be a problem.

I've run into that with my toy lisp interpreter which tries
to do bitfields arithmetically on signed integers.

https://github.com/luser-dr00g/sexp.c/blob/4c8ccf05d45f36bba2e866736cc101d1d404f45c/sexp.c#L253
    assert((-1>>1)==-1);	/*require 2's-complement and right-shift must be sign-preserving */

Is there a better way to make this assertion?
Can it (even theoretically) be checked at compile time
to produce an #error?

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


#93760

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2016-09-18 17:04 -0400
Message-ID<eaa5435d-a0df-38be-80cf-1aef1b96325b@verizon.net>
In reply to#93756
On 09/18/2016 04:26 PM, luser droog wrote:
> On Sunday, September 18, 2016 at 9:20:08 AM UTC-5, James R. Kuyper wrote:
[Re: right shift of an int value]
...
>> If x is negative, the result of the shift operation is
>> implementation-defined. That's not as bad as undefined behavior, but
>> it's bad enough to be a problem.
>
> I've run into that with my toy lisp interpreter which tries
> to do bitfields arithmetically on signed integers.
>
> https://github.com/luser-dr00g/sexp.c/blob/4c8ccf05d45f36bba2e866736cc101d1d404f45c/sexp.c#L253
>     assert((-1>>1)==-1);	/*require 2's-complement and right-shift must be sign-preserving */
>
> Is there a better way to make this assertion?
> Can it (even theoretically) be checked at compile time
> to produce an #error?

Theoretically, an implementation's freedom to define the result when x 
is negative includes defining (-1>>1)==-1, while defining (x>>1), for 
some or all x<-1, to have a value different from the one you were 
expecting. The only way to be certain is to check every value of x from 
INT_MIN to -1. That could be problematic if INT_MIN == 
-9223372036854775807, which is true on some platforms.
The better solution is to avoid applying >> to negative values, using 
some other method of calculating the quantity you want.

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


#93885

FromTim Rentsch <txr@alumni.caltech.edu>
Date2016-09-22 01:21 -0700
Message-ID<kfnd1jwfipf.fsf@x-alumni2.alumni.caltech.edu>
In reply to#93756
luser droog <luser.droog@gmail.com> writes:

> On Sunday, September 18, 2016 at 9:20:08 AM UTC-5, James R.  Kuyper wrote:
>> On 09/17/2016 08:19 PM, Ben Bacarisse wrote:
>>> Malcolm McLean <malcolm.mclean5@btinternet.com> writes:
>>> <snip>
>>>> The temptation is to write fput16le like this
>>>>
>>>> /* don't use this, broken example */
>>>> fput16le(int x)
>>>> {
>>>>   fputc(x & 0xFF, fp);
>>>>   fputc( (x >> 8) &0xFF, fp);
>>>> }
>>>>
>>>> I used that code for a long time with no problems.  But it's
>>>> undefined behaviour and thus technically incorrect as C code.
>>>
>>> Is this another case of Malcolm-speak?  It's not undefined in the C
>>> standard sense of the word. ...
>>
>> If x is negative, the result of the shift operation is
>> implementation-defined.  That's not as bad as undefined
>> behavior, but it's bad enough to be a problem.
>
> I've run into that with my toy lisp interpreter which tries
> to do bitfields arithmetically on signed integers.
>
> https://github.com/luser-dr00g/sexp.c/blob/
>   4c8ccf05d45f36bba2e866736cc101d1d404f45c/sexp.c#L253
>
>     assert((-1>>1)==-1); /* require 2's-complement and
>                             right-shift must be sign-preserving */
>
> Is there a better way to make this assertion?

There are two separate conditions you want to test;  therefore
should be two distinct predicates being tested, as for example

  assert( (-1 & 3) == 3 );  /* that ints are 2's complement */
  assert( (-1 >> 1) < 0 );  /* that right shift keeps sign  */

> Can it (even theoretically) be checked at compile time
> to produce an #error?

Not an #error, but there is a common way to force a diagnostic if
the predicate is not met (here 'assert_phantom' is arbitrary):

  extern int assert_phantom[ (-1 & 3) == 3 ? 1 : -1 ];

If the predicate isn't satisfied then the array extent will be
negative, which requires a diagnostic.

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


#93563

FromTim Rentsch <txr@alumni.caltech.edu>
Date2016-09-15 12:07 -0700
Message-ID<kfnoa3pgewn.fsf@x-alumni2.alumni.caltech.edu>
In reply to#93526
David Brown <david.brown@hesbynett.no> writes:

> On 14/09/16 05:47, Tim Rentsch wrote:
>> David Brown <david.brown@hesbynett.no> writes:
>>
>>> On 13/09/16 15:24, Malcolm McLean wrote:
>>>> Yes, it seems the problem doesn't really exist.  There's already a mechanism
>>>> built in to solve it.  The read is a bit tricky, but the write is easy, even on
>>>> one's complement machines.  (The snag with these routines is that you can't
>>>> get hold of a non-two's complement, non CHAR_BIT == 8 implementation
>>>> to test them).
>>>
>>> Are you just doing this for fun, or do you really expect the code to be
>>> useful on ones-complement machines?
>>>
>>> There are systems in current use that have CHAR_BIT != 8, but I'd be
>>> surprised to find one with a hosted environment rather than a standalone
>>> environment (i.e., embedded DSP systems), and thus you are unlikely to
>>> have "fputc" (you certainly can't rely on it).
>>>
>>> I just wondering what the practical uses are of writing code that is
>>> supposed to be portable to machines that are not one's complement, or
>>> have CHAR_BIT != 8, but which needs fputc to write to a file.
>>
>> To me this reaction seems backwards.  One should normally take the
>> stance that code will be written to be platform portable, and fall
>> back to platform-specific code only when writing platform-agnostic
>> code proves too arduous.  In this particular case it's easier to
>> write code that works for all the integer encoding schemes than it
>> is to write code that works for only some of them, so the decision
>> there seems like a total no-brainer.  Similarly CHAR_BIT > 8 is not
>> a problem if one doesn't mind using only 8 bits of however many
>> there are available - better to have code that works with a lower
>> efficiency on those platforms than to simply rule them out just
>> because CHAR_BIT > 8.
>
> I think we have quite a different viewpoint here.  I am not trying
> to have an argument here, or say "I'm right and you are wrong".

Neither one of us is right, or wrong, since in both cases all
that is being offered is personal opinion.

> In particular, I know we work on rather different kinds of code
> (the irony being that I may well have worked on a wider range of
> targets than you).

The remark in parentheses is very likely true along some axes,
and very likely false along others.

> What follows is an attempt at sharing a my
> different viewpoint on portable code, as an exchange of ideas and
> opinions.
>
> Note - I know that in this particular case, the integer encoding does
> not affect the code.  I'm making a more general point here.
>
>
>
> I have nothing against writing code that happens to work on all
> conforming systems.  Most code involving integers is valid or
> invalid regardless of the integer encoding scheme.  My question is
> whether or not it is worth /considering/ something like integer
> encoding.
>
> In the case of Malcolm's code here, it is written in connection
> with his Baby X project.  Is there /any/ possibility that it would
> ever be run on a machine that does not have two's complement
> integers?  Is there any possibility that someone will look at that
> code, and use it for inspiration or learning, when writing code
> that will run on machines with different integer encoding?
>
> If the answers are no, then it is a waste of time (except for fun
> or education) even thinking about the issue.  It is certainly a
> waste of time and effort to write code intentionally in a way that
> is agnostic to the integer encoding.  And if keeping it so
> portable means poorer generated code on real-world systems, then
> you have definitely lost out.
>
> Code is written for a variety of purposes, and you generally have
> a range of goals in mind.  Portability and re-use is often part of
> that, but rarely the most important goal.  And so you have a
> balancing act - do you make assumptions that reduce portability,
> but improve other goals such as code clarity, or run-time
> efficiency?
>
> And when you are thinking about portability, what should be your aims?
> Do you concern yourself with systems that are conforming C but almost
> non-existent in reality (such as one's complement platforms)?  Do you
> concern yourself with systems that are totally hypothetical but could
> exist (such as a system with CHAR_BIT == 27)?  Do you concern yourself
> with systems that are /not/ conforming, but /do/ exist?

(My comments are not meant to address any matters outside the
realm of conforming C.  I hope we can confine the discussion to
that domain.)

> There are
> billions of microcontrollers in use where the development tools support
> a language that is mostly C, but not quite.  For example, they might
> have 8-bit int, or not support implicit promotion to int (or unsigned
> int), in order to generate more efficient code on small processors.

I believe I understand your position (ie, just in the context of
talking about conforming C implementations), and the reasons you
have offered to motivate those opinions.

I believe you do not yet understand what I am advocating here.
I'm sorry to just leave it at that in this response, but I'm at a
loss right now as to what further explanation to give.


> So if I need a function that turns an int into an unsigned 16-bit
> integer, I would normally write:
>
> uint16_t toUint16(int x) {
>     return x;
> }
>
> It would be more portable if I wrote:
>
> uint_least16_t toUint16(int x) {
>     uint_least16_t y = x;
>     return y & 0xffff;
> }
>
> But the first version will run on almost all real-life systems,
> including most processors we are likely to see in the future.  And on
> the few devices that don't support such code, like the Analog Devices
> SHARC dsps, you'll get a clear compile-time error - there is no risk of
> silently producing incorrect code.
>
> And on many real-life systems, the first version will give more
> efficient run-time code - and it will never give /worse/ code.

It isn't hard to supply this functionality in a way that is
portable to platforms that do not have a uint16_t type, but still
is just as efficient on those platforms where it can be.  As the
amount of effort needed is comparable in the two approaches, ISTM
that a more portable version is a better choice.  Furthermore
cases like this can be accumulated in a general library so the
effort involved is amortized over all the code bases where such
things are needed.

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


#93585

FromDavid Brown <david.brown@hesbynett.no>
Date2016-09-16 00:32 +0200
Message-ID<nrf7hm$n7t$1@dont-email.me>
In reply to#93563
On 15/09/16 21:07, Tim Rentsch wrote:
> David Brown <david.brown@hesbynett.no> writes:
>
>> On 14/09/16 05:47, Tim Rentsch wrote:
>>> David Brown <david.brown@hesbynett.no> writes:
>>>
>>>> On 13/09/16 15:24, Malcolm McLean wrote:
>>>>> Yes, it seems the problem doesn't really exist.  There's already a mechanism
>>>>> built in to solve it.  The read is a bit tricky, but the write is easy, even on
>>>>> one's complement machines.  (The snag with these routines is that you can't
>>>>> get hold of a non-two's complement, non CHAR_BIT == 8 implementation
>>>>> to test them).
>>>>
>>>> Are you just doing this for fun, or do you really expect the code to be
>>>> useful on ones-complement machines?
>>>>
>>>> There are systems in current use that have CHAR_BIT != 8, but I'd be
>>>> surprised to find one with a hosted environment rather than a standalone
>>>> environment (i.e., embedded DSP systems), and thus you are unlikely to
>>>> have "fputc" (you certainly can't rely on it).
>>>>
>>>> I just wondering what the practical uses are of writing code that is
>>>> supposed to be portable to machines that are not one's complement, or
>>>> have CHAR_BIT != 8, but which needs fputc to write to a file.
>>>
>>> To me this reaction seems backwards.  One should normally take the
>>> stance that code will be written to be platform portable, and fall
>>> back to platform-specific code only when writing platform-agnostic
>>> code proves too arduous.  In this particular case it's easier to
>>> write code that works for all the integer encoding schemes than it
>>> is to write code that works for only some of them, so the decision
>>> there seems like a total no-brainer.  Similarly CHAR_BIT > 8 is not
>>> a problem if one doesn't mind using only 8 bits of however many
>>> there are available - better to have code that works with a lower
>>> efficiency on those platforms than to simply rule them out just
>>> because CHAR_BIT > 8.
>>
>> I think we have quite a different viewpoint here.  I am not trying
>> to have an argument here, or say "I'm right and you are wrong".
>
> Neither one of us is right, or wrong, since in both cases all
> that is being offered is personal opinion.

Agreed.  I just wanted to be clear here, in case it looked like I was 
being argumentative (that happens sometimes).

>
>> In particular, I know we work on rather different kinds of code
>> (the irony being that I may well have worked on a wider range of
>> targets than you).
>
> The remark in parentheses is very likely true along some axes,
> and very likely false along others.

Agreed.  It might be interesting to compare sometime.

>
>> What follows is an attempt at sharing a my
>> different viewpoint on portable code, as an exchange of ideas and
>> opinions.
>>
>> Note - I know that in this particular case, the integer encoding does
>> not affect the code.  I'm making a more general point here.
>>
>>
>>
>> I have nothing against writing code that happens to work on all
>> conforming systems.  Most code involving integers is valid or
>> invalid regardless of the integer encoding scheme.  My question is
>> whether or not it is worth /considering/ something like integer
>> encoding.
>>
>> In the case of Malcolm's code here, it is written in connection
>> with his Baby X project.  Is there /any/ possibility that it would
>> ever be run on a machine that does not have two's complement
>> integers?  Is there any possibility that someone will look at that
>> code, and use it for inspiration or learning, when writing code
>> that will run on machines with different integer encoding?
>>
>> If the answers are no, then it is a waste of time (except for fun
>> or education) even thinking about the issue.  It is certainly a
>> waste of time and effort to write code intentionally in a way that
>> is agnostic to the integer encoding.  And if keeping it so
>> portable means poorer generated code on real-world systems, then
>> you have definitely lost out.
>>
>> Code is written for a variety of purposes, and you generally have
>> a range of goals in mind.  Portability and re-use is often part of
>> that, but rarely the most important goal.  And so you have a
>> balancing act - do you make assumptions that reduce portability,
>> but improve other goals such as code clarity, or run-time
>> efficiency?
>>
>> And when you are thinking about portability, what should be your aims?
>> Do you concern yourself with systems that are conforming C but almost
>> non-existent in reality (such as one's complement platforms)?  Do you
>> concern yourself with systems that are totally hypothetical but could
>> exist (such as a system with CHAR_BIT == 27)?  Do you concern yourself
>> with systems that are /not/ conforming, but /do/ exist?
>
> (My comments are not meant to address any matters outside the
> realm of conforming C.  I hope we can confine the discussion to
> that domain.)

I realise you prefer to stick to conforming C in discussions - it can be 
very difficult to reason about something that breaks the rules unless we 
can limit exactly /which/ rules are broken, and in which ways (i.e., we 
can provide new rules).  Certainly it is impossible to write code that 
will work on a particular near-C compiler unless we know exactly how it 
works.

So I am not suggesting that code should be written in a way that will 
work with any near-C compiler.  I am merely raising the question, should 
some of these compilers be considered when writing code that should be 
portable?

As an example, portable embedded code is sometimes written with explicit 
initialisation for all global or file-scope variables, even if their 
initial value is 0:

	static int x = 0;

rather than
	
	static int x;

They do this because there are embedded compilers (notably TI's "Code 
composer" compilers - sometimes referred to as "Code composter") which 
do not zero-initialise such variables.

>
>> There are
>> billions of microcontrollers in use where the development tools support
>> a language that is mostly C, but not quite.  For example, they might
>> have 8-bit int, or not support implicit promotion to int (or unsigned
>> int), in order to generate more efficient code on small processors.
>
> I believe I understand your position (ie, just in the context of
> talking about conforming C implementations), and the reasons you
> have offered to motivate those opinions.
>
> I believe you do not yet understand what I am advocating here.
> I'm sorry to just leave it at that in this response, but I'm at a
> loss right now as to what further explanation to give.
>
>
>> So if I need a function that turns an int into an unsigned 16-bit
>> integer, I would normally write:
>>
>> uint16_t toUint16(int x) {
>>      return x;
>> }
>>
>> It would be more portable if I wrote:
>>
>> uint_least16_t toUint16(int x) {
>>      uint_least16_t y = x;
>>      return y & 0xffff;
>> }
>>
>> But the first version will run on almost all real-life systems,
>> including most processors we are likely to see in the future.  And on
>> the few devices that don't support such code, like the Analog Devices
>> SHARC dsps, you'll get a clear compile-time error - there is no risk of
>> silently producing incorrect code.
>>
>> And on many real-life systems, the first version will give more
>> efficient run-time code - and it will never give /worse/ code.
>
> It isn't hard to supply this functionality in a way that is
> portable to platforms that do not have a uint16_t type, but still
> is just as efficient on those platforms where it can be.  As the
> amount of effort needed is comparable in the two approaches, ISTM
> that a more portable version is a better choice.  Furthermore
> cases like this can be accumulated in a general library so the
> effort involved is amortized over all the code bases where such
> things are needed.
>

It is possible that it would surprise you just how inefficient some 
compilers are.  For the most part, I have access to good compilers 
(mostly gcc, sometimes other good quality compilers).  But I have had 
occasion to use ones that do a much poorer job - I have one for an 8-bit 
target that would generate two 8-bit "AND 0xff" instructions and a 
number of register moves for the second version of the function above.

And in terms of "portability", one might consider "portable to different 
programmers" as well as "portable to different compilers and targets". 
There is a depressingly large proportion of C programmers who don't know 
much about their tools, and fail to enable even basic optimisations. 
Should we write code in a way that minimises the inefficiency this 
causes, or should we just say that if those users don't care about their 
runtime efficiency, we shouldn't care about their runtime efficiency 
either?  I am not trying to answer that question, merely raising it.

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


#93590

Fromsupercat@casperkitty.com
Date2016-09-15 16:30 -0700
Message-ID<d9ff6994-0e2b-43d9-8405-98ecc436d414@googlegroups.com>
In reply to#93585
On Thursday, September 15, 2016 at 5:32:38 PM UTC-5, David Brown wrote:
> There is a depressingly large proportion of C programmers who don't know 
> much about their tools, and fail to enable even basic optimisations. 
> Should we write code in a way that minimises the inefficiency this 
> causes, or should we just say that if those users don't care about their 
> runtime efficiency, we shouldn't care about their runtime efficiency 
> either?  I am not trying to answer that question, merely raising it.

The majority of code in many applications will be orders of magnitude
faster than it needs to be, even without optimization.  If failure to
enable an optimization causes a program to run unacceptably slowly,
research into where the program is spending its time should fairly
quickly identify an area of the code that should be inspected to find
out whether some optimizations may be enabled safely.

If, by contrast, a compiler decides that given something like:

   /* Assume int is 32 bits */
    uint32_t fetch_32le(uint8_t *p)
    {
      return p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
    }

it should in some cases omit code that would check whether p[3] is
greater than 127, the only evidence that such a thing has occurred
may be some random data corruption that occurs for no apparent reason
when a function which is supposed to be run only with values less than
128 gets run with larger values.  Note that adding an "assert" within
the function to check whether the value is less than 128 might not
help: if the optimizer is enabled, it will decide the value "can't" be
greater than 128, and omit the assertion, while if it isn't enabled the
function will never get called with values greater than 128.

The authors of the C Standard have indicated in their rationale that they
would expect that commonplace implementations would process the above
function correctly.  Should the fact that the Standard would allow an
implementation to do otherwise be taken as implying that a quality
implementation for a two's-complement platform *should* do so?

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


#93593

FromKeith Thompson <kst-u@mib.org>
Date2016-09-15 18:35 -0700
Message-ID<lnpoo41v9r.fsf@kst-u.example.com>
In reply to#93590
supercat@casperkitty.com writes:
[...]
> The authors of the C Standard have indicated in their rationale that they
> would expect that commonplace implementations would process the above
> function correctly.  Should the fact that the Standard would allow an
> implementation to do otherwise be taken as implying that a quality
> implementation for a two's-complement platform *should* do so?

You should start a blog so you can make these points without re-writing
them every time.

(Don't worry, this is the last time I'll do this.)

-- 
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]


#93597

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2016-09-15 22:00 -0700
Message-ID<ca461687-ec2b-4ac1-ba1d-f1f2408b1cbe@googlegroups.com>
In reply to#93585
On Thursday, September 15, 2016 at 11:32:38 PM UTC+1, David Brown wrote:
>
> And in terms of "portability", one might consider "portable to different 
> programmers" as well as "portable to different compilers and targets". 
> There is a depressingly large proportion of C programmers who don't know 
> much about their tools, and fail to enable even basic optimisations. 
> Should we write code in a way that minimises the inefficiency this 
> causes, or should we just say that if those users don't care about their 
> runtime efficiency, we shouldn't care about their runtime efficiency 
> either?  I am not trying to answer that question, merely raising it.
>
The general rule is "write the thing in C or it's a thundering 
nuisance to anyone else trying to use your code". The main portability
problem is type aliasing. It's common to see geometrical functions
which expose something like struct{double x, double y} Point, then
you've got a few functions like "length". For the sake of a few
trivial subroutines, something quite sophisticated, like a Voroni
finder, is broken and unusable, and needs rewriting before it can
be used. 
In C++ the problem is far worse, because someone will have
written a "Point2" class with lots of nice features, maybe even 
overloading the "-" operator to return a "Vector2". Cute. But then
it's not just  a case of systematically going through and replacing
the the "Point"s with x and y. The whole Point2 machinery needs
ripping out and replacing with whatever you are using.

It's even worse if your type alias is on integers. Most integers
need to be big enough to index the arrays the functions that
operate on those arrays are passed. But essentially every function
uses integers. If the language does not have an accepted, conventional,
aways-used keyword for declaring an integer, it's on the skids. It 
is no longer a suitable medium for communication of subroutines.

But a function that takes an "int" and writes it as a 16 bit-little
endian two's complement representation to a file should be portable
to anything that supports binary file io. There's no reason for it
not to be. 

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


#93599

Fromsupercat@casperkitty.com
Date2016-09-15 22:17 -0700
Message-ID<1f96be72-1df4-4955-a444-5d8f52a1d162@googlegroups.com>
In reply to#93597
On Friday, September 16, 2016 at 12:00:36 AM UTC-5, Malcolm McLean wrote:
> The general rule is "write the thing in C or it's a thundering 
> nuisance to anyone else trying to use your code". The main portability
> problem is type aliasing. It's common to see geometrical functions
> which expose something like struct{double x, double y} Point, then
> you've got a few functions like "length". For the sake of a few
> trivial subroutines, something quite sophisticated, like a Voroni
> finder, is broken and unusable, and needs rewriting before it can
> be used.

It's a shame that some people think programmers should have to jump through
hoops to exchange data between a function that expects a pointer to a

   struct point {double x, double y; };

and another function that expects a pointer to a 

   struct point2d {double x, double y; };

even when both structures contain members with the same names and types.
It's good that compilers require casts when converting between pointers
to layout-compatible types, since types may be layout compatible but have
different semantics, but that doesn't mean there shouldn't be a usable way
to convert pointers.

In C89, it was at least possible to use memmove() to block aliasing
assumptions, and a smart implementation might notice at runtime that the
two pointers were equal and skip the actual copy operation (but retain
the alias-blocking semantics).  Since C99 changed the semantics of memmove
so that it is no longer a barrier to aliasing analysis, however, I don't
think there is an efficient way to force the compiler that some storage
which had been accessed as one type is going to be accessed as another.

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


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

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


csiph-web