Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #74838 > unrolled thread
| Started by | G G <gdotone@gmail.com> |
|---|---|
| First post | 2015-11-04 06:22 -0800 |
| Last post | 2015-11-05 21:24 -0800 |
| Articles | 20 on this page of 184 — 23 participants |
Back to article view | Back to comp.lang.c
One over another: (*structp).component structp->component G G <gdotone@gmail.com> - 2015-11-04 06:22 -0800
Re: One over another: (*structp).component structp->component Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-11-04 09:37 -0500
Re: One over another: (*structp).component structp->component G G <gdotone@gmail.com> - 2015-11-04 06:59 -0800
Re: One over another: (*structp).component structp->component Bartc <bc@freeuk.com> - 2015-11-04 15:52 +0000
Re: One over another: (*structp).component structp->component Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-04 22:05 +0000
Re: One over another: (*structp).component structp->component Bartc <bc@freeuk.com> - 2015-11-04 22:20 +0000
Re: One over another: (*structp).component structp->component Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-04 23:32 +0000
Re: One over another: (*structp).component structp->component "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-11-04 15:55 -0800
Re: One over another: (*structp).component structp->component Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-05 00:21 +0000
Re: One over another: (*structp).component structp->component "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-11-04 15:58 -0800
Re: One over another: (*structp).component structp->component Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-05 00:26 +0000
Re: One over another: (*structp).component structp->component supercat@casperkitty.com - 2015-11-04 16:27 -0800
Re: One over another: (*structp).component structp->component Bartc <bc@freeuk.com> - 2015-11-05 00:25 +0000
Re: One over another: (*structp).component structp->component Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-05 00:59 +0000
Re: One over another: (*structp).component structp->component Bartc <bc@freeuk.com> - 2015-11-05 01:22 +0000
Re: One over another: (*structp).component structp->component Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-05 10:30 +0000
Re: One over another: (*structp).component structp->component Keith Thompson <kst-u@mib.org> - 2015-11-04 18:09 -0800
Re: One over another: (*structp).component structp->component Bartc <bc@freeuk.com> - 2015-11-06 01:08 +0000
Re: One over another: (*structp).component structp->component Richard Heathfield <rjh@cpax.org.uk> - 2015-11-06 01:19 +0000
Re: One over another: (*structp).component structp->component Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-06 11:30 +0000
Re: One over another: (*structp).component structp->component Bartc <bc@freeuk.com> - 2015-11-06 11:55 +0000
Re: One over another: (*structp).component structp->component Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-06 13:29 +0000
Re: One over another: (*structp).component structp->component Bartc <bc@freeuk.com> - 2015-11-06 14:00 +0000
Re: One over another: (*structp).component structp->component Bartc <bc@freeuk.com> - 2015-11-06 14:24 +0000
Re: One over another: (*structp).component structp->component Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-06 16:58 +0000
Re: One over another: (*structp).component structp->component Bartc <bc@freeuk.com> - 2015-11-06 17:55 +0000
Re: One over another: (*structp).component structp->component Richard Heathfield <rjh@cpax.org.uk> - 2015-11-06 18:07 +0000
Re: One over another: (*structp).component structp->component Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-06 19:51 +0000
Re: One over another: (*structp).component structp->component Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-11-06 13:09 -0500
Re: One over another: (*structp).component structp->component Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2015-11-06 13:15 -0500
Re: One over another: (*structp).component structp->component Bartc <bc@freeuk.com> - 2015-11-06 18:58 +0000
Re: One over another: (*structp).component structp->component supercat@casperkitty.com - 2015-11-06 10:30 -0800
Re: One over another: (*structp).component structp->component Bartc <bc@freeuk.com> - 2015-11-06 19:09 +0000
Re: One over another: (*structp).component structp->component Keith Thompson <kst-u@mib.org> - 2015-11-06 12:35 -0800
Re: One over another: (*structp).component structp->component Keith Thompson <kst-u@mib.org> - 2015-11-06 12:38 -0800
Re: One over another: (*structp).component structp->component Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-06 19:43 +0000
Re: One over another: (*structp).component structp->component raltbos@xs4all.nl (Richard Bos) - 2015-11-10 16:39 +0000
Re: One over another: (*structp).component structp->component BartC <bc@freeuk.com> - 2015-11-10 17:28 +0000
Re: One over another: (*structp).component structp->component Richard Heathfield <rjh@cpax.org.uk> - 2015-11-10 18:04 +0000
Re: One over another: (*structp).component structp->component Keith Thompson <kst-u@mib.org> - 2015-11-10 11:19 -0800
Re: One over another: (*structp).component structp->component BartC <bc@freeuk.com> - 2015-11-10 21:04 +0000
Re: One over another: (*structp).component structp->component Keith Thompson <kst-u@mib.org> - 2015-11-10 13:31 -0800
Re: One over another: (*structp).component structp->component Richard Heathfield <rjh@cpax.org.uk> - 2015-11-10 22:15 +0000
Re: One over another: (*structp).component structp->component BartC <bc@freeuk.com> - 2015-11-10 23:33 +0000
Re: One over another: (*structp).component structp->component Richard Heathfield <rjh@cpax.org.uk> - 2015-11-10 23:59 +0000
Re: One over another: (*structp).component structp->component Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-11 10:46 +0000
Re: One over another: (*structp).component structp->component BartC <bc@freeuk.com> - 2015-11-11 11:01 +0000
Re: One over another: (*structp).component structp->component Keith Thompson <kst-u@mib.org> - 2015-11-11 08:43 -0800
Re: One over another: (*structp).component structp->component BartC <bc@freeuk.com> - 2015-11-11 16:58 +0000
Re: One over another: (*structp).component structp->component supercat@casperkitty.com - 2015-11-11 09:14 -0800
Re: One over another: (*structp).component structp->component glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-11-18 00:47 +0000
Re: One over another: (*structp).component structp->component Richard Heathfield <rjh@cpax.org.uk> - 2015-11-18 04:12 +0000
Re: One over another: (*structp).component structp->component Keith Thompson <kst-u@mib.org> - 2015-11-17 20:27 -0800
Re: One over another: (*structp).component structp->component glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-11-18 08:11 +0000
Re: One over another: (*structp).component structp->component Keith Thompson <kst-u@mib.org> - 2015-11-17 20:14 -0800
Re: One over another: (*structp).component structp->component glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-11-18 08:14 +0000
Re: One over another: (*structp).component structp->component James Kuyper <jameskuyper@verizon.net> - 2015-11-18 08:12 -0500
Re: One over another: (*structp).component structp->component glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-11-18 14:33 +0000
Re: One over another: (*structp).component structp->component Keith Thompson <kst-u@mib.org> - 2015-11-18 09:05 -0800
Re: One over another: (*structp).component structp->component glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-11-18 23:16 +0000
Re: One over another: (*structp).component structp->component James Kuyper <jameskuyper@verizon.net> - 2015-11-18 18:23 -0500
Re: One over another: (*structp).component structp->component glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-11-19 00:27 +0000
Re: One over another: (*structp).component structp->component Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-19 00:44 +0000
Re: One over another: (*structp).component structp->component glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-11-19 04:11 +0000
Re: One over another: (*structp).component structp->component James Kuyper <jameskuyper@verizon.net> - 2015-11-19 00:19 -0500
Re: One over another: (*structp).component structp->component BartC <bc@freeuk.com> - 2015-11-19 00:52 +0000
Re: One over another: (*structp).component structp->component Keith Thompson <kst-u@mib.org> - 2015-11-20 02:24 -0800
Re: One over another: (*structp).component structp->component glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-11-20 15:07 +0000
Re: One over another: (*structp).component structp->component Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-11-20 10:19 -0500
Re: One over another: (*structp).component structp->component Philip Lantz <prl@canterey.us> - 2015-11-23 00:06 -0800
Re: One over another: (*structp).component structp->component Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-18 16:21 +0000
Re: One over another: (*structp).component structp->component James Kuyper <jameskuyper@verizon.net> - 2015-11-18 13:29 -0500
Re: One over another: (*structp).component structp->component Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-18 22:00 +0000
Re: One over another: (*structp).component structp->component Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-11-18 17:33 -0500
Re: One over another: (*structp).component structp->component Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-20 15:38 -0800
Re: One over another: (*structp).component structp->component glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-11-18 23:23 +0000
Re: One over another: (*structp).component structp->component Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-19 00:12 +0000
Re: One over another: (*structp).component structp->component glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-11-12 09:00 +0000
Re: One over another: (*structp).component structp->component BartC <bc@freeuk.com> - 2015-11-12 10:12 +0000
Re: One over another: (*structp).component structp->component Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-11 17:31 +0000
Re: One over another: (*structp).component structp->component BartC <bc@freeuk.com> - 2015-11-11 18:42 +0000
Re: One over another: (*structp).component structp->component Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-11 23:38 +0000
Re: One over another: (*structp).component structp->component David Brown <david.brown@hesbynett.no> - 2015-11-11 10:56 +0100
Re: One over another: (*structp).component structp->component BartC <bc@freeuk.com> - 2015-11-11 10:52 +0000
Re: One over another: (*structp).component structp->component Keith Thompson <kst-u@mib.org> - 2015-11-11 08:28 -0800
Re: One over another: (*structp).component structp->component Richard Heathfield <rjh@cpax.org.uk> - 2015-11-11 16:52 +0000
Re: One over another: (*structp).component structp->component Richard Heathfield <rjh@cpax.org.uk> - 2015-11-11 16:35 +0000
Re: One over another: (*structp).component structp->component Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-10 15:43 -0800
Re: One over another: (*structp).component structp->component raltbos@xs4all.nl (Richard Bos) - 2015-11-13 22:13 +0000
Re: One over another: (*structp).component structp->component BartC <bc@freeuk.com> - 2015-11-13 23:52 +0000
Re: One over another: (*structp).component structp->component raltbos@xs4all.nl (Richard Bos) - 2015-11-17 22:02 +0000
Re: One over another: (*structp).component structp->component BartC <bc@freeuk.com> - 2015-11-17 23:56 +0000
Re: One over another: (*structp).component structp->component Keith Thompson <kst-u@mib.org> - 2015-11-17 20:10 -0800
Re: One over another: (*structp).component structp->component BartC <bc@freeuk.com> - 2015-11-18 11:51 +0000
Re: One over another: (*structp).component structp->component raltbos@xs4all.nl (Richard Bos) - 2015-11-19 10:33 +0000
Re: One over another: (*structp).component structp->component raltbos@xs4all.nl (Richard Bos) - 2015-11-19 10:23 +0000
Re: One over another: (*structp).component structp->component BartC <bc@freeuk.com> - 2015-11-19 11:46 +0000
Re: One over another: (*structp).component structp->component Keith Thompson <kst-u@mib.org> - 2015-11-06 11:13 -0800
Re: One over another: (*structp).component structp->component Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-06 19:42 +0000
Re: One over another: (*structp).component structp->component Keith Thompson <kst-u@mib.org> - 2015-11-04 16:33 -0800
Re: One over another: (*structp).component structp->component Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-11-04 13:11 -0500
Re: One over another: (*structp).component structp->component G G <gdotone@gmail.com> - 2015-11-04 11:49 -0800
Re: One over another: (*structp).component structp->component Richard Heathfield <rjh@cpax.org.uk> - 2015-11-04 20:00 +0000
Re: One over another: (*structp).component structp->component Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-11-04 15:36 -0500
Re: One over another: (*structp).component structp->component Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-04 15:16 -0800
Re: One over another: (*structp).component structp->component "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-11-04 15:28 -0800
Re: One over another: (*structp).component structp->component supercat@casperkitty.com - 2015-11-04 16:25 -0800
Re: One over another: (*structp).component structp->component Richard Heathfield <rjh@cpax.org.uk> - 2015-11-05 00:47 +0000
Re: One over another: (*structp).component structp->component Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-04 19:24 -0800
Re: One over another: (*structp).component structp->component Ian Collins <ian-news@hotmail.com> - 2015-11-05 16:34 +1300
Re: One over another: (*structp).component structp->component Richard Heathfield <rjh@cpax.org.uk> - 2015-11-05 09:39 +0000
Re: One over another: (*structp).component structp->component David Brown <david.brown@hesbynett.no> - 2015-11-05 13:45 +0100
Re: One over another: (*structp).component structp->component Richard Heathfield <rjh@cpax.org.uk> - 2015-11-05 13:30 +0000
Re: One over another: (*structp).component structp->component Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-05 08:14 -0800
Re: One over another: (*structp).component structp->component G G <gdotone@gmail.com> - 2015-11-05 08:25 -0800
Re: One over another: (*structp).component structp->component Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-11-05 12:00 -0500
Re: One over another: (*structp).component structp->component G G <gdotone@gmail.com> - 2015-11-05 09:09 -0800
Re: One over another: (*structp).component structp->component "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-11-05 11:02 -0800
Re: One over another: (*structp).component structp->component supercat@casperkitty.com - 2015-11-05 09:28 -0800
Re: One over another: (*structp).component structp->component Keith Thompson <kst-u@mib.org> - 2015-11-05 12:50 -0800
Re: One over another: (*structp).component structp->component supercat@casperkitty.com - 2015-11-05 13:38 -0800
Re: One over another: (*structp).component structp->component Keith Thompson <kst-u@mib.org> - 2015-11-05 17:29 -0800
Re: One over another: (*structp).component structp->component supercat@casperkitty.com - 2015-11-05 17:43 -0800
Re: One over another: (*structp).component structp->component supercat@casperkitty.com - 2015-11-05 20:02 -0800
Re: One over another: (*structp).component structp->component Keith Thompson <kst-u@mib.org> - 2015-11-06 08:01 -0800
Re: One over another: (*structp).component structp->component supercat@casperkitty.com - 2015-11-06 08:35 -0800
Re: One over another: (*structp).component structp->component Keith Thompson <kst-u@mib.org> - 2015-11-06 11:10 -0800
Re: One over another: (*structp).component structp->component supercat@casperkitty.com - 2015-11-06 13:35 -0800
Re: One over another: (*structp).component structp->component Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-06 12:04 -0800
Re: One over another: (*structp).component structp->component Keith Thompson <kst-u@mib.org> - 2015-11-06 13:14 -0800
Re: One over another: (*structp).component structp->component Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-10 13:40 -0800
Re: One over another: (*structp).component structp->component Keith Thompson <kst-u@mib.org> - 2015-11-10 14:13 -0800
Re: One over another: (*structp).component structp->component Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-13 05:36 -0800
Re: One over another: (*structp).component structp->component supercat@casperkitty.com - 2015-11-13 14:32 -0800
Re: One over another: (*structp).component structp->component Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-14 12:09 -0800
Re: One over another: (*structp).component structp->component raltbos@xs4all.nl (Richard Bos) - 2015-11-17 22:03 +0000
Re: One over another: (*structp).component structp->component David Thompson <dave.thompson2@verizon.net> - 2015-12-06 07:56 -0500
Re: One over another: (*structp).component structp->component G G <gdotone@gmail.com> - 2015-11-05 09:26 -0800
Re: One over another: (*structp).component structp->component Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-05 18:06 +0000
Re: One over another: (*structp).component structp->component G G <gdotone@gmail.com> - 2015-11-05 10:10 -0800
Re: One over another: (*structp).component structp->component G G <gdotone@gmail.com> - 2015-11-05 14:08 -0800
Re: One over another: (*structp).component structp->component supercat@casperkitty.com - 2015-11-05 14:24 -0800
Re: One over another: (*structp).component structp->component James Kuyper <jameskuyper@verizon.net> - 2015-11-05 18:08 -0500
Re: One over another: (*structp).component structp->component G G <gdotone@gmail.com> - 2015-11-05 17:13 -0800
Re: One over another: (*structp).component structp->component James Kuyper <jameskuyper@verizon.net> - 2015-11-05 13:08 -0500
Re: One over another: (*structp).component structp->component supercat@casperkitty.com - 2015-11-05 10:33 -0800
Re: One over another: (*structp).component structp->component James Kuyper <jameskuyper@verizon.net> - 2015-11-05 21:44 -0500
Re: One over another: (*structp).component structp->component David Brown <david.brown@hesbynett.no> - 2015-11-05 10:38 +0100
Re: One over another: (*structp).component structp->component Reinhardt Behm <rbehm@hushmail.com> - 2015-11-05 21:01 +0800
Re: One over another: (*structp).component structp->component James Kuyper <jameskuyper@verizon.net> - 2015-11-05 09:06 -0500
Re: One over another: (*structp).component structp->component "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-11-05 06:11 -0800
Re: One over another: (*structp).component structp->component Richard Heathfield <rjh@cpax.org.uk> - 2015-11-05 14:19 +0000
Re: One over another: (*structp).component structp->component Keith Thompson <kst-u@mib.org> - 2015-11-05 09:20 -0800
Re: One over another: (*structp).component structp->component James Kuyper <jameskuyper@verizon.net> - 2015-11-05 12:56 -0500
Re: One over another: (*structp).component structp->component raltbos@xs4all.nl (Richard Bos) - 2015-11-06 11:32 +0000
Re: One over another: (*structp).component structp->component David Brown <david.brown@hesbynett.no> - 2015-11-05 20:26 +0100
Re: One over another: (*structp).component structp->component Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-05 07:50 -0800
Re: One over another: (*structp).component structp->component Martin Shobe <martin.shobe@yahoo.com> - 2015-11-05 11:46 -0600
Re: One over another: (*structp).component structp->component Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-06 11:33 -0800
Re: One over another: (*structp).component structp->component Philip Lantz <prl@canterey.us> - 2015-11-07 00:32 -0800
Re: One over another: (*structp).component structp->component Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-13 03:43 -0800
Re: One over another: (*structp).component structp->component David Brown <david.brown@hesbynett.no> - 2015-11-07 20:03 +0100
Re: One over another: (*structp).component structp->component raltbos@xs4all.nl (Richard Bos) - 2015-11-10 16:42 +0000
Re: One over another: (*structp).component structp->component Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-13 04:03 -0800
Re: One over another: (*structp).component structp->component G G <gdotone@gmail.com> - 2015-11-04 19:42 -0800
Re: One over another: (*structp).component structp->component Reinhardt Behm <rbehm@hushmail.com> - 2015-11-05 12:54 +0800
Re: One over another: (*structp).component structp->component Bartc <bc@freeuk.com> - 2015-11-05 10:36 +0000
Re: One over another: (*structp).component structp->component Reinhardt Behm <rbehm@hushmail.com> - 2015-11-05 20:46 +0800
Re: One over another: (*structp).component structp->component supercat@casperkitty.com - 2015-11-05 09:02 -0800
Re: One over another: (*structp).component structp->component raltbos@xs4all.nl (Richard Bos) - 2015-11-06 11:07 +0000
Re: One over another: (*structp).component structp->component Richard Heathfield <rjh@cpax.org.uk> - 2015-11-06 11:26 +0000
Re: One over another: (*structp).component structp->component raltbos@xs4all.nl (Richard Bos) - 2015-11-06 15:58 +0000
Re: One over another: (*structp).component structp->component Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2015-11-06 11:10 -0500
Re: One over another: (*structp).component structp->component Philip Lantz <prl@canterey.us> - 2015-11-07 01:13 -0800
Re: One over another: (*structp).component structp->component Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2015-11-07 11:11 -0500
Re: One over another: (*structp).component structp->component raltbos@xs4all.nl (Richard Bos) - 2015-11-10 16:47 +0000
Re: One over another: (*structp).component structp->component Siri Cruz <chine.bleu@yahoo.com> - 2015-11-04 06:49 -0800
Re: One over another: (*structp).component structp->component James Kuyper <jameskuyper@verizon.net> - 2015-11-04 09:55 -0500
Re: One over another: (*structp).component structp->component G G <gdotone@gmail.com> - 2015-11-04 07:00 -0800
Re: One over another: (*structp).component structp->component James Kuyper <jameskuyper@verizon.net> - 2015-11-04 13:19 -0500
Re: One over another: (*structp).component structp->component Richard Heathfield <rjh@cpax.org.uk> - 2015-11-04 16:17 +0000
Re: One over another: (*structp).component structp->component "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-11-04 14:53 -0800
Re: One over another: (*structp).component structp->component supercat@casperkitty.com - 2015-11-04 15:29 -0800
Re: One over another: (*structp).component structp->component luser droog <luser.droog@gmail.com> - 2015-11-05 21:24 -0800
Page 7 of 10 — ← Prev page 1 … 5 6 [7] 8 9 10 Next page →
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-11-05 13:38 -0800 |
| Subject | Re: One over another: (*structp).component structp->component |
| Message-ID | <e97ae5dd-f90b-4357-a35f-69d6179d6032@googlegroups.com> |
| In reply to | #75015 |
On Thursday, November 5, 2015 at 2:50:22 PM UTC-6, Keith Thompson wrote: > If you read a number (either integer or floating-point) and the input > has the expected form but represents a value outside the range of > the type, the behavior is undefined. This makes it impossible > to use any of the *scanf functions safely for numeric input. > I believe that's the case even for unsigned integers. A simple and cheap remedy would be to fix the Standard to require that the implementation must either return an Unspecified (not Intdeterminate!) value or trap in a manner that may, via implementation-defined means, be configured to cause an abnormal program termination. I suspect 99% of implementations would "naturally" be in compliance, and I would be surprised if any would require adding more than two instructions to the cost of any existing scanf implementation (at worst, to force a conversion from an Indeterminate value to an Unspecified value), but it would make the functions infinitely safer.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-11-05 17:29 -0800 |
| Subject | Re: One over another: (*structp).component structp->component |
| Message-ID | <lntwoz52zs.fsf@kst-u.example.com> |
| In reply to | #75025 |
supercat@casperkitty.com writes:
> On Thursday, November 5, 2015 at 2:50:22 PM UTC-6, Keith Thompson wrote:
>> If you read a number (either integer or floating-point) and the input
>> has the expected form but represents a value outside the range of
>> the type, the behavior is undefined. This makes it impossible
>> to use any of the *scanf functions safely for numeric input.
>> I believe that's the case even for unsigned integers.
>
> A simple and cheap remedy would be to fix the Standard to require that the
> implementation must either return an Unspecified (not Intdeterminate!) value
> or trap in a manner that may, via implementation-defined means, be configured
> to cause an abnormal program termination.
Why make it so complicated?
The fix I'd like to see is that if a numeric input is outside the
range of the expected type, it's treated like a matching failure,
though perhaps with some differences regarding how much of the
input is consumed.
For example, currently this:
int n1, n2;
sscanf("123 999999999999999999", "%d %d", &n1, &n2);
has undefined behavior. I suggest that it should return 1, store
123 in n1, and not modify n2, just as it would if the input string
were "123 xyz".
The strto*() functions already have well defined behavior in the
presence of overflowing (or ill-formed) input. I can't think of any
reason not to require *scanf() to behave equally sensibly, or to permit
different implementations to behave differently.
The implementation-defined abnormal program termination that you suggest
is only barely better than undefined behavior; it still would makes it
impossible for an application to handle bad input gracefully.
> I suspect 99% of implementations would "naturally" be in compliance,
> and I would be surprised if any would require adding more than two
> instructions to the cost of any existing scanf implementation (at
> worst, to force a conversion from an Indeterminate value to an
> Unspecified value), but it would make the functions infinitely safer.
With the implementation I'm currently using (gcc with glibc), sscanf()
returns 2 and n2 is set to -1. It doesn't blow up, but the incorrect
input is not detectable.
--
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-11-05 17:43 -0800 |
| Subject | Re: One over another: (*structp).component structp->component |
| Message-ID | <7b265a76-b823-45cc-a46e-a3b7fb0dc323@googlegroups.com> |
| In reply to | #75040 |
On Thursday, November 5, 2015 at 7:30:15 PM UTC-6, Keith Thompson wrote: > supercat writes: > > A simple and cheap remedy would be to fix the Standard to require that the > > implementation must either return an Unspecified (not Intdeterminate!) value > > or trap in a manner that may, via implementation-defined means, be configured > > to cause an abnormal program termination. > > Why make it so complicated? To have the definition be consistent with the behavior of essentially all existing non-capricious implementations. I would expect that there probably exist implementations where overflows will cause an abnormal program termination, and where invalid data received from scanf can cause such overflows (and such consequent program termination) and I have no particular desire to declare such implementations non-conforming especially since it's entirely possible that some programs might rely upon such behavior to prevent the production of seemingly-valid-but-wrong output.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-11-05 20:02 -0800 |
| Subject | Re: One over another: (*structp).component structp->component |
| Message-ID | <3e5fb9e7-6d8b-4e07-855d-392ff9d11caa@googlegroups.com> |
| In reply to | #75040 |
On Thursday, November 5, 2015 at 7:30:15 PM UTC-6, Keith Thompson wrote: > The implementation-defined abnormal program termination that you suggest > is only barely better than undefined behavior; it still would makes it > impossible for an application to handle bad input gracefully. I'll agree that scanf isn't designed to handle bad input gracefully, but there is an enormous difference between saying that bad input is allowed to terminate a program and saying that it's allowed to grant the supplier of bad input the ability to execute arbitrary code. IMHO, the vast majority of actions that invoke Undefined Behavior would have been much more usefully specified as a category of behavior which required implementations to document the range of possible consequences, but would allow an implementation to say that an action could have unbounded consequences if wasn't possible to be more specific.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-11-06 08:01 -0800 |
| Subject | Re: One over another: (*structp).component structp->component |
| Message-ID | <lnmvur3ymh.fsf@kst-u.example.com> |
| In reply to | #75044 |
supercat@casperkitty.com writes:
> On Thursday, November 5, 2015 at 7:30:15 PM UTC-6, Keith Thompson wrote:
>> The implementation-defined abnormal program termination that you suggest
>> is only barely better than undefined behavior; it still would makes it
>> impossible for an application to handle bad input gracefully.
>
> I'll agree that scanf isn't designed to handle bad input gracefully,
> but there is an enormous difference between saying that bad input is
> allowed to terminate a program and saying that it's allowed to grant
> the supplier of bad input the ability to execute arbitrary code.
> IMHO, the vast majority of actions that invoke Undefined Behavior
> would have been much more usefully specified as a category of behavior
> which required implementations to document the range of possible
> consequences, but would allow an implementation to say that an action
> could have unbounded consequences if wasn't possible to be more
> specific.
With the change you suggest, if I understand it correctly, I can't
detect and handle a numeric overflow in *scanf(). Either it gives
me a seemingly valid result with no way of detecting the error,
or it traps and terminates the program. Sure, it's better than
undefined behavior, but it still means that the only reasonable
course of action is to avoid using *scanf() for numeric input.
The change I suggest (treating numeric overflow as an error)
would only define behavior that is currently undefined. Any code
that depends on that undefined behavior, or on what a particular
implementation does, is already broken. Such code probably already
handles input errors (like reading "xyz" when it's expecting an
integer).
--
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-11-06 08:35 -0800 |
| Subject | Re: One over another: (*structp).component structp->component |
| Message-ID | <4942e280-cd7c-49f3-bd3a-25bb03967fbf@googlegroups.com> |
| In reply to | #75109 |
On Friday, November 6, 2015 at 10:02:07 AM UTC-6, Keith Thompson wrote: > The change I suggest (treating numeric overflow as an error) > would only define behavior that is currently undefined. Any code > that depends on that undefined behavior, or on what a particular > implementation does, is already broken. Such code probably already > handles input errors (like reading "xyz" when it's expecting an > integer). The difficulty is that there may be existing programs which are reliant upon the target implementation's scanf terminating the program to prevent it from proceeding with seemingly-valid-but-wrong input; even if your proposal would provide a means by which incorrect input could be detected, existing code may not recognize that. It's too bad many people don't understand the former historical semantic significance of Undefined Behavior. C wasn't designed to be a language for writing machine-independent code--it was designed to be a family of dialects that could be used to write code for many varied individual machines, which would provide a variety of features which could be useful for a variety of kinds of programs which had to meet a variety of needs. Some programs were required never to produce seemingly-valid-but-wrong output in case of things like numeric overflow; if the program couldn't produce correct output, it needed to terminate abnormally rather than produce wrong output. Other programs were expected to process a mixture of valid and invalid data, and were required to produce correct output for the correct data, and any output, within broad limits, for the invalid data. Some hardware platforms favor the first kind of program, and some favor the second; C was designed not to discriminate against either kind of platform but instead allow either kind of platform to expose its semantics so that code whose semantics fit the platform could let the platform handle overflow in the fashion required without needing to have the compiler *or the human programmer* write code to deal with overflow. What C lacks is a means by which programs can indicate which form of semantics they require. Back when C was designed, there wasn't any need for that--a program could simply be presumed to require the semantics of the implementation for which it was written. What's tragic is that decades later, despite adding a huge amount of complexity to the language, the Committee has shown absolutely no interest in turning C's biggest weakness (the fact that there's no way to specify any behavior which isn't universal to all implementations) into a huge strength (allowing programmers to use features that are present on some but not implementations, when writing code which only needs to run on platforms supporting those features).
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-11-06 11:10 -0800 |
| Subject | Re: One over another: (*structp).component structp->component |
| Message-ID | <lnwptv2bbr.fsf@kst-u.example.com> |
| In reply to | #75118 |
supercat@casperkitty.com writes:
> On Friday, November 6, 2015 at 10:02:07 AM UTC-6, Keith Thompson wrote:
>> The change I suggest (treating numeric overflow as an error)
>> would only define behavior that is currently undefined. Any code
>> that depends on that undefined behavior, or on what a particular
>> implementation does, is already broken. Such code probably already
>> handles input errors (like reading "xyz" when it's expecting an
>> integer).
>
> The difficulty is that there may be existing programs which are
> reliant upon the target implementation's scanf terminating the program
> to prevent it from proceeding with seemingly-valid-but-wrong input;
> even if your proposal would provide a means by which incorrect input
> could be detected, existing code may not recognize that.
I'm skeptical that such programs exist in any significant numbers.
Examples would be welcome.
If they do, then that *might* be a reason not to go with my proposal
to treat numeric overflow as a detectable error. But I suggest
that backward compatibility would be the *only* valid reason to
consider either staying with the current definition or adopting
yours. And again, it would affect only programs whose behavior is
currently undefined.
If you want to write a program that reads an integer from a text
stream and terminates if it's outside the range of the target type,
you can already do that by calling fgets() followed by one of the
strto*() functions, calling abort() if necessary. Depending on
*scanf() to do that for you would be foolish. (And aborting on
bad input is rarely a good idea anyway.)
In the one implementation I've tried, a numeric overflow resulted
in the value -1 being assigned to the variable, with no indication
that there was a problem. A hypothetical program that assumes
abnormal termination would misbehave.
For that matter, can you cite an existing implementation in
which numeric overflow in *scanf() causes termination of the
calling program? If, as I tentatively suspect, there are no such
implementations, then there can be no programs that depend on
such behavior.
If you were designing a formatted text input function from
scratch, would you even consider making the behavior on numeric
overflow either undefined, implementation-defined, or unspecified?
The strto*() functions (which I believe were added to the language
after *scanf() already existed) have well defined behavior on
overflow. Why should *scanf() be different?
> It's too bad many people don't understand the former historical
> semantic significance of Undefined Behavior. C wasn't designed to be
> a language for writing machine-independent code--it was designed to be
> a family of dialects that could be used to write code for many varied
> individual machines, which would provide a variety of features which
> could be useful for a variety of kinds of programs which had to meet a
> variety of needs.
C intentionally makes it possible both to write portable code and to
write non-portable system-specific code. This goes back at least
to K&R1, 1978, which lists 4 different target systems, at least
one of which was chosen specifically to be as different from the
PDP-11 as possible. I can think of no good reason for the *scanf()
functions to be restricted to non-portable usage.
> Some programs were required never to produce seemingly-valid-but-wrong
> output in case of things like numeric overflow; if the program
> couldn't produce correct output, it needed to terminate abnormally
> rather than produce wrong output.
Then it's too bad that C has *never* required a program to terminate
abnormally on an error (barring an explicit call to abort() or something
similar). (C11's Annex K says that an implementation has a default
runtime constraint handler; it may or may not cause the program to exit
or abort.)
[...]
A side note. I've noticed that the text in most of your articles is
quite close to 80 columns, which means it goes past 80 columns when
it's quoted (triggering a warning from my newsreader). Would it
be difficult for you to format your text to, say, 72 columns?
(I often use `fmt -70` myself.)
--
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-11-06 13:35 -0800 |
| Subject | Re: One over another: (*structp).component structp->component |
| Message-ID | <0263b2aa-a70f-4997-949e-44a975bfe885@googlegroups.com> |
| In reply to | #75157 |
On Friday, November 6, 2015 at 1:10:41 PM UTC-6, Keith Thompson wrote: > supercat writes: > > The difficulty is that there may be existing programs which are > > reliant upon the target implementation's scanf terminating the program > > to prevent it from proceeding with seemingly-valid-but-wrong input; > > even if your proposal would provide a means by which incorrect input > > could be detected, existing code may not recognize that. > > I'm skeptical that such programs exist in any significant numbers. > Examples would be welcome. I haven't used C on platforms which trap overflows, but I know that such platforms exist. As to whether some code might exist somewhere which relies upon that behavior, I would consider it plausible. I would also consider it likely (and upon some consideration, recognize that my proposed definition was a little too strict) that implementations may perform other actions which would fall outside the realm of the Standard but could nonetheless be useful. I'm unclear on whether sscanf would be allowed to set errno in any defined cases, for example [variations of scanf which take input from a stream set errno for stream-realted problems but not format-related ones], but it would certainly be plausible that an implementation might set errno as a means of indicating an attempt to read a number larger than INT_MAX into an int. Further, while it wouldn't work for sscanf, it's entirely plausible that an implementation of "scanf" might send an error message to the console when an invalid input is received and invite the user to try again. Nothing in the Standard would particularly allow such behavior, but nothing would forbid it either. > If they do, then that *might* be a reason not to go with my proposal > to treat numeric overflow as a detectable error. But I suggest > that backward compatibility would be the *only* valid reason to > consider either staying with the current definition or adopting > yours. And again, it would affect only programs whose behavior is > currently undefined. Programs whose behavior is *currently not defined by the Standard* (something which is true of most programs). Some implementations do define the behavior of scanf-related functions when given invalid inputs, and so the behavior of programs receiving bad input is well-defined on such systems. > If you want to write a program that reads an integer from a text > stream and terminates if it's outside the range of the target type, > you can already do that by calling fgets() followed by one of the > strto*() functions, calling abort() if necessary. Depending on > *scanf() to do that for you would be foolish. (And aborting on > bad input is rarely a good idea anyway.) Whether aborting on bad input is a good idea or a bad idea depends upon the program's requirements. For some programs, the worst possible action may be to produce seemingly-valid-but-wrong output. In today's world that's not as common as when C was in its infancy (in the 1970s it was not uncommon to run C programs on systems which lacked the physical ability to erase any important information, but if numerical overflow caused a program to report that e.g. an under-sized beam would be strong enough to support the required load, that could be disastrous) but that doesn't mean that abnormal program termination wouldn't be preferable to seemingly-valid-but-wrong output. All that has changed is the possibility of even worse alternatives. > In the one implementation I've tried, a numeric overflow resulted > in the value -1 being assigned to the variable, with no indication > that there was a problem. A hypothetical program that assumes > abnormal termination would misbehave. Someone needing a program to run on such an implementation probably would not have relied on such behavior. > For that matter, can you cite an existing implementation in > which numeric overflow in *scanf() causes termination of the > calling program? If, as I tentatively suspect, there are no such > implementations, then there can be no programs that depend on > such behavior. I don't know of all C compilers in existence, but the Standard sometimes goes out of its way to support even less plausible ones. > If you were designing a formatted text input function from > scratch, would you even consider making the behavior on numeric > overflow either undefined, implementation-defined, or unspecified? > The strto*() functions (which I believe were added to the language > after *scanf() already existed) have well defined behavior on > overflow. Why should *scanf() be different? If I were designing a standard library, I'd do a lot of things differently. I'd allow for quite a variety of behavior on code which accepts input from the console, though I'd require that implementations document what they're going to do. If an implementation documented that its read-number-from- console would keep re-prompting until the user entered a valid number, such behavior would be reasonable; if a later version of the OS allowed console redirection, having a compiler for such a platform quit if the file contains invalid data rather than proceeding onward (which would not have happened using real console I/O) would be more of a breaking change than terminating the code [if the user never provided entered valid input, the balance of the code would never execute, and terminating a program that can't finish seems better than hanging in and endless loop for something that is never going to happen]. > > It's too bad many people don't understand the former historical > > semantic significance of Undefined Behavior. C wasn't designed to be > > a language for writing machine-independent code--it was designed to be > > a family of dialects that could be used to write code for many varied > > individual machines, which would provide a variety of features which > > could be useful for a variety of kinds of programs which had to meet a > > variety of needs. > > C intentionally makes it possible both to write portable code and to > write non-portable system-specific code. This goes back at least > to K&R1, 1978, which lists 4 different target systems, at least > one of which was chosen specifically to be as different from the > PDP-11 as possible. I can think of no good reason for the *scanf() > functions to be restricted to non-portable usage. What about the self-prompting console-I/O pattern? Remember that on many platforms console I/O was totally different from file I/O. > > Some programs were required never to produce seemingly-valid-but-wrong > > output in case of things like numeric overflow; if the program > > couldn't produce correct output, it needed to terminate abnormally > > rather than produce wrong output. > > Then it's too bad that C has *never* required a program to terminate > abnormally on an error (barring an explicit call to abort() or something > similar). (C11's Annex K says that an implementation has a default > runtime constraint handler; it may or may not cause the program to exit > or abort.) C has never required it, because in many application fields other behaviors are both more useful and cheaper to implement. It has never forbidden such behavior either, however, since there are some application fields where it is the best behavior, and there are some platforms where it's the cheapest. If C were to forbid implementations from terminating on signed integer overflow, but didn't specify what value should be produced, and someone were writing a program which needed to trap on overflow, on a platform which would naturally trap on overflow, then what could have been a=b+c; would have to be written by the programmer as something much more big and complicated containing multiple additions and subtractions. Worse, *each* of those would have to be expanded by the compiler into a multi-instruction sequence whose sub-components could be guaranteed not to overflow. The net effect would be that the final program would probably run an order of magnitude slower than if C had allowed the implementation to simply trap overflows. > A side note. I've noticed that the text in most of your articles is > quite close to 80 columns, which means it goes past 80 columns when > it's quoted (triggering a warning from my newsreader). Would it > be difficult for you to format your text to, say, 72 columns? > (I often use `fmt -70` myself.) Google Groups uses an 80-column window and I try to stay a little distance from the edge. I have no idea why someone the size of Google doesn't seem to care at all about Usenet conventions (if a user types a big long line it will show up in the editor as a formatted paragraph, but post as a big long line) but I still try to be reasonable.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-11-06 12:04 -0800 |
| Subject | Re: One over another: (*structp).component structp->component |
| Message-ID | <kfnr3k251yl.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #75040 |
Keith Thompson <kst-u@mib.org> writes:
> supercat@casperkitty.com writes:
>> On Thursday, November 5, 2015 at 2:50:22 PM UTC-6, Keith Thompson wrote:
>>> If you read a number (either integer or floating-point) and the
>>> input has the expected form but represents a value outside the
>>> range of the type, the behavior is undefined. This makes it
>>> impossible to use any of the *scanf functions safely for numeric
>>> input. I believe that's the case even for unsigned integers.
>>
>> A simple and cheap remedy would be to fix the Standard to require
>> that the implementation must either return an Unspecified (not
>> Intdeterminate!) value or trap in a manner that may, via
>> implementation-defined means, be configured to cause an abnormal
>> program termination.
>
> Why make it so complicated?
>
> The fix I'd like to see is that if a numeric input is outside the
> range of the expected type, it's treated like a matching failure,
> though perhaps with some differences regarding how much of the
> input is consumed.
>
> For example, currently this:
>
> int n1, n2;
> sscanf("123 999999999999999999", "%d %d", &n1, &n2);
>
> has undefined behavior. I suggest that it should return 1, store
> 123 in n1, and not modify n2, just as it would if the input string
> were "123 xyz".
>
> The strto*() functions already have well defined behavior in the
> presence of overflowing (or ill-formed) input. I can't think of
> any reason not to require *scanf() to behave equally sensibly, or
> to permit different implementations to behave differently. [snip]
Let me point out a subtlety that you may have overlooked. I
believe the Standard allows, and is intended to allow, calls to
scanf() involving constructions like the following:
unsigned u;
scanf( "%d", &u );
What I mean by "allow" is that the behavior is defined, provided
the value read is non-negative and not larger than INT_MAX (which
implies that it is not larger than UINT_MAX). Note the wording
for the relevant paragraph in the description of fscanf(), which
is consistent with this conclusion: "/an/ appropriate type", not
"the appropriate type" (my emphasis), and also other portions of
that same sentence.
If this kind of construction is indeed meant to be allowed, that
presents a difficulty for your proposed modification. A call to
one of the strtol() functions can specify defined behavior for
out-of-range values precisely because there is only one type to
consider. When there is more than one type that may qualify, the
out-of-rangeness question is not one the library function can
answer. An in-range value for a signed int may produce a trap
representation when stored in an unsigned int object (and vice
versa, obviously).
Given the above, how can the problem be resolved? My guess is
that possibilities like the above example are what prompted the
choice of undefined behavior in the first place.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-11-06 13:14 -0800 |
| Subject | Re: One over another: (*structp).component structp->component |
| Message-ID | <ln37wi3k4y.fsf@kst-u.example.com> |
| In reply to | #75174 |
Tim Rentsch <txr@alumni.caltech.edu> writes:
> Keith Thompson <kst-u@mib.org> writes:
[...]
>> The strto*() functions already have well defined behavior in the
>> presence of overflowing (or ill-formed) input. I can't think of
>> any reason not to require *scanf() to behave equally sensibly, or
>> to permit different implementations to behave differently. [snip]
>
> Let me point out a subtlety that you may have overlooked.
I knew I could count on you! 8-)}
> I
> believe the Standard allows, and is intended to allow, calls to
> scanf() involving constructions like the following:
>
> unsigned u;
> scanf( "%d", &u );
>
> What I mean by "allow" is that the behavior is defined, provided
> the value read is non-negative and not larger than INT_MAX (which
> implies that it is not larger than UINT_MAX). Note the wording
> for the relevant paragraph in the description of fscanf(), which
> is consistent with this conclusion: "/an/ appropriate type", not
> "the appropriate type" (my emphasis), and also other portions of
> that same sentence.
I don't think so. N1570 7.21.6.2p12:
d Matches an optionally signed decimal integer, whose format is
the same as expected for the subject sequence of the strtol
function with the value 10 for the base argument. The
corresponding argument shall be a pointer to signed integer.
The use of an unsigned* argument violates the "shall", resulting in
undefined behavior. I don't propose changing that.
In practice it's very likely to behave as expected for values in the
range 0..INT_MAX.
The "%d" format specifies that the input must have the form of an
optionally signed integer constant, and that its value must be within
the range INT_MIN .. INT_MAX. The fact that the resulting int value
(in case of success) is (ignoring the UB) then copied to an object
of type unsigned int doesn't affect any checking done by scanf().
I'm not sure what to make of the phrase "an appropriate type" rather
than "the appropriate type". Perhaps it's meant to refer to the fact
that type correct type varies with different formats, but as far as I
can tell each format specifies a unique required type, with undefined
behavior if a different type is used.
[...]
--
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 | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-11-10 13:40 -0800 |
| Subject | Re: One over another: (*structp).component structp->component |
| Message-ID | <kfn4mgth6tn.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #75185 |
Keith Thompson <kst-u@mib.org> writes:
> Tim Rentsch <txr@alumni.caltech.edu> writes:
>> Keith Thompson <kst-u@mib.org> writes:
>
> [...]
>
>>> The strto*() functions already have well defined behavior in the
>>> presence of overflowing (or ill-formed) input. I can't think of
>>> any reason not to require *scanf() to behave equally sensibly, or
>>> to permit different implementations to behave differently. [snip]
>>
>> Let me point out a subtlety that you may have overlooked.
>
> I knew I could count on you! 8-)}
>
>> I
>> believe the Standard allows, and is intended to allow, calls to
>> scanf() involving constructions like the following:
>>
>> unsigned u;
>> scanf( "%d", &u );
>>
>> What I mean by "allow" is that the behavior is defined, provided
>> the value read is non-negative and not larger than INT_MAX (which
>> implies that it is not larger than UINT_MAX). Note the wording
>> for the relevant paragraph in the description of fscanf(), which
>> is consistent with this conclusion: "/an/ appropriate type", not
>> "the appropriate type" (my emphasis), and also other portions of
>> that same sentence.
>
> I don't think so. N1570 7.21.6.2p12:
>
> d Matches an optionally signed decimal integer, whose format is
> the same as expected for the subject sequence of the strtol
> function with the value 10 for the base argument. The
> corresponding argument shall be a pointer to signed integer.
>
> The use of an unsigned* argument violates the "shall", resulting in
> undefined behavior. I don't propose changing that.
Oh yeah. I think I have had this pointed out to me before
but I forgot.
However, I believe there is still a related problem. Consider
this calling sequence:
unsigned u;
scanf( "%d", (signed *) &u );
Now we haven't violated the "shall" sentence (taking that to be a
statment about the type of the argument, which I think it what's
intended), but we still have a problem storing a value that isn't
in the intersection of the two types' values. This possibility
also explains why the aforementioned paragraph talks about "/an/
appropriate type" rather than "the appropriate type", and why it
references the type of the object being stored into rather than
just the type of the argument pointer.
> In practice it's very likely to behave as expected for values in the
> range 0..INT_MAX.
>
> The "%d" format specifies that the input must have the form of an
> optionally signed integer constant, and that its value must be within
> the range INT_MIN .. INT_MAX. The fact that the resulting int value
> (in case of success) is (ignoring the UB) then copied to an object
> of type unsigned int doesn't affect any checking done by scanf().
I believe the "shall" undefined behavior here is meant to
reference the type of the argument, not the type of the object
being stored into. There may also be undefined behavior if
effective type rules are violated, but those rules specifically
allow using the corresponding signed or unsigned type (for integer
types).
> I'm not sure what to make of the phrase "an appropriate type" rather
> than "the appropriate type". Perhaps it's meant to refer to the fact
> that type correct type varies with different formats, but as far as I
> can tell each format specifies a unique required type, with undefined
> behavior if a different type is used.
The argument (pointer) type is uniquely determined by the format;
the type of the object to be stored into is not. That distinction
explains both: the "shall" requirement; and the phrase "an
appropriate type", and referring to the object that the value is
placed in (rather than referring again to the argument type).
Of course, it still would be possible to add a rule that says
anything outside the range of the argument type would be treated
the same way as a match failure. But that would still leave a
potential undefined behavior for storing into an object whose
type cannot represent the value to be stored.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-11-10 14:13 -0800 |
| Subject | Re: One over another: (*structp).component structp->component |
| Message-ID | <lny4e5sdst.fsf@kst-u.example.com> |
| In reply to | #75683 |
Tim Rentsch <txr@alumni.caltech.edu> writes:
> Keith Thompson <kst-u@mib.org> writes:
[...]
>> The use of an unsigned* argument violates the "shall", resulting in
>> undefined behavior. I don't propose changing that.
>
> Oh yeah. I think I have had this pointed out to me before
> but I forgot.
>
> However, I believe there is still a related problem. Consider
> this calling sequence:
>
> unsigned u;
> scanf( "%d", (signed *) &u );
Ok, that's legitimate. The effective type rules (N1570 6.5p7) aren't
directly relevant, since they discuss accessing the stored value of an
object and we're not doing that here, but I think it's reasonable to
assume that if the input is in the range 0..INT_MAX, then that value
will be stored in u. (Proving that is left as an exercise for the
pedant.)
Which means that "an appropriate type" (N1570 7.21.6.2p10) could be
either int or unsigned int, because of the partial interchangeability of
those types. I don't see anything explicit in the standard to support
that.
For a value outside that range, specifically a negative value, I suppose
the value of u is implementation-defined and can be determined by the
representation of int and unsigned int.
So -- what's the problem? The scanf call is treating u as if it were an
object of type signed int. The behavior is determined by the format.
Assume 16-bit 2's-complement int (just to save typing). Currently, the
behavior is undefined if the input is, for example, "-32659" or "32768".
In my proposal, either of those inputs would be treated like a matching
failure, causing scanf() to return 0. The fact that the actual type of
u is unsigned int would not affect that, only the interpretation of the
value (if any) after it's been stored.
> Now we haven't violated the "shall" sentence (taking that to be a
> statment about the type of the argument, which I think it what's
> intended), but we still have a problem storing a value that isn't
> in the intersection of the two types' values. This possibility
> also explains why the aforementioned paragraph talks about "/an/
> appropriate type" rather than "the appropriate type", and why it
> references the type of the object being stored into rather than
> just the type of the argument pointer.
I'd say it's not scanf's job to worry about that. It's no different
from any other method of storing an int value in an unsigned object:
unsigned u;
*(int*)u = -1;
>> In practice it's very likely to behave as expected for values in the
>> range 0..INT_MAX.
>>
>> The "%d" format specifies that the input must have the form of an
>> optionally signed integer constant, and that its value must be within
>> the range INT_MIN .. INT_MAX. The fact that the resulting int value
>> (in case of success) is (ignoring the UB) then copied to an object
>> of type unsigned int doesn't affect any checking done by scanf().
>
> I believe the "shall" undefined behavior here is meant to
> reference the type of the argument, not the type of the object
> being stored into. There may also be undefined behavior if
> effective type rules are violated, but those rules specifically
> allow using the corresponding signed or unsigned type (for integer
> types).
It says:
Unless assignment suppression was indicated by a *, the result of
the conversion is placed in the object pointed to by the first
argument following the format argument that has not already
received a conversion result. If this object does not have an
appropriate type, or if the result of the conversion cannot be
represented in the object, the behavior is undefined.
Is "the object pointed to" of type int (what the pointer points to), or
unsigned (how the object was defined)? If both types are "appropriate",
I suppose it doesn't matter.
>> I'm not sure what to make of the phrase "an appropriate type" rather
>> than "the appropriate type". Perhaps it's meant to refer to the fact
>> that type correct type varies with different formats, but as far as I
>> can tell each format specifies a unique required type, with undefined
>> behavior if a different type is used.
>
> The argument (pointer) type is uniquely determined by the format;
> the type of the object to be stored into is not. That distinction
> explains both: the "shall" requirement; and the phrase "an
> appropriate type", and referring to the object that the value is
> placed in (rather than referring again to the argument type).
>
> Of course, it still would be possible to add a rule that says
> anything outside the range of the argument type would be treated
> the same way as a match failure. But that would still leave a
> potential undefined behavior for storing into an object whose
> type cannot represent the value to be stored.
Sure, if the types don't match the behavior is undefined. I don't
suggest changing that, since it's easy to avoid by writing correct code.
All I propose changing is the currently undefined behavior that cannot
be avoided without restricting the input.
--
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 | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-11-13 05:36 -0800 |
| Subject | Re: One over another: (*structp).component structp->component |
| Message-ID | <kfnoaeyqavm.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #75687 |
Keith Thompson <kst-u@mib.org> writes:
> Tim Rentsch <txr@alumni.caltech.edu> writes:
>> Keith Thompson <kst-u@mib.org> writes:
>
> [...]
>
>>> The use of an unsigned* argument violates the "shall", resulting in
>>> undefined behavior. I don't propose changing that.
>>
>> Oh yeah. I think I have had this pointed out to me before
>> but I forgot.
>>
>> However, I believe there is still a related problem. Consider
>> this calling sequence:
>>
>> unsigned u;
>> scanf( "%d", (signed *) &u );
>
> Ok, that's legitimate. The effective type rules (N1570 6.5p7)
> aren't directly relevant, since they discuss accessing the stored
> value of an object and we're not doing that here,
I think you're misreading the requirements here. Effective type
rules apply to write access as well as read access. The stored
value is being "accessed" - it is being written!
> but I think it's reasonable to assume that if the input is in the
> range 0..INT_MAX, then that value will be stored in u. (Proving
> that is left as an exercise for the pedant.)
>
> Which means that "an appropriate type" (N1570 7.21.6.2p10) could be
> either int or unsigned int, because of the partial interchangeability
> of those types. I don't see anything explicit in the standard to
> support that.
AFAIK there isn't any explicit statement. It just seems to me to
be the most natural way of reading it. Not the most obvious
perhaps, but the most natural.
> For a value outside that range, specifically a negative value, I
> suppose the value of u is implementation-defined and can be
> determined by the representation of int and unsigned int.
I mostly agree, except that padding bits and trap representations
may complicate the issue.
> So -- what's the problem? The scanf call is treating u as if it were
> an object of type signed int. The behavior is determined by the
> format. Assume 16-bit 2's-complement int (just to save typing).
> Currently, the behavior is undefined if the input is, for example,
> "-32659" or "32768".
I'm just making a note here for something I will get to further
on.
> In my proposal, either of those inputs would be treated like a
> matching failure, causing scanf() to return 0. The fact that the
> actual type of u is unsigned int would not affect that, only the
> interpretation of the value (if any) after it's been stored.
Yes, I understood that (and tried to say as much further on).
>> Now we haven't violated the "shall" sentence (taking that to be a
>> statment about the type of the argument, which I think it what's
>> intended), but we still have a problem storing a value that isn't
>> in the intersection of the two types' values. This possibility
>> also explains why the aforementioned paragraph talks about "/an/
>> appropriate type" rather than "the appropriate type", and why it
>> references the type of the object being stored into rather than
>> just the type of the argument pointer.
>
> I'd say it's not scanf's job to worry about that. It's no different
> from any other method of storing an int value in an unsigned object:
>
> unsigned u;
> *(int*)u = -1;
My comment was not so much about scanf(), just about how to
understand the reasoning for why the text is worded as it is.
>>> In practice it's very likely to behave as expected for values in the
>>> range 0..INT_MAX.
>>>
>>> The "%d" format specifies that the input must have the form of an
>>> optionally signed integer constant, and that its value must be within
>>> the range INT_MIN .. INT_MAX. The fact that the resulting int value
>>> (in case of success) is (ignoring the UB) then copied to an object
>>> of type unsigned int doesn't affect any checking done by scanf().
>>
>> I believe the "shall" undefined behavior here is meant to
>> reference the type of the argument, not the type of the object
>> being stored into. There may also be undefined behavior if
>> effective type rules are violated, but those rules specifically
>> allow using the corresponding signed or unsigned type (for integer
>> types).
>
> It says:
>
> Unless assignment suppression was indicated by a *, the result of
> the conversion is placed in the object pointed to by the first
> argument following the format argument that has not already
> received a conversion result. If this object does not have an
> appropriate type, or if the result of the conversion cannot be
> represented in the object, the behavior is undefined.
>
> Is "the object pointed to" of type int (what the pointer points to),
> or unsigned (how the object was defined)?
I took it to be the type as the object was defined (ie, unsigned
in this case). Otherwise there is no point in asking whether the
object has an appropriate type, since the type the pointer points
to is always appropriate for the type the pointer points to.
> If both types are
> "appropriate", I suppose it doesn't matter.
>
>>> I'm not sure what to make of the phrase "an appropriate type" rather
>>> than "the appropriate type". Perhaps it's meant to refer to the fact
>>> that type correct type varies with different formats, but as far as I
>>> can tell each format specifies a unique required type, with undefined
>>> behavior if a different type is used.
>>
>> The argument (pointer) type is uniquely determined by the format;
>> the type of the object to be stored into is not. That distinction
>> explains both: the "shall" requirement; and the phrase "an
>> appropriate type", and referring to the object that the value is
>> placed in (rather than referring again to the argument type).
>>
>> Of course, it still would be possible to add a rule that says
>> anything outside the range of the argument type would be treated
>> the same way as a match failure. But that would still leave a
>> potential undefined behavior for storing into an object whose
>> type cannot represent the value to be stored.
>
> Sure, if the types don't match the behavior is undefined.
I think you mean "don't match" here in a different way than
what I have described. Storing into an object whose effective
type is unsigned should "match" a %d conversion specifier.
The determining factor is the value stored, not the type (ie, for
cases like signed/unsigned int).
> I don't suggest changing that, since it's easy to avoid by
> writing correct code. All I propose changing is the currently
> undefined behavior that cannot be avoided without restricting
> the input.
Earlier you said this:
> Currently, the behavior is undefined if the input is, for
> example, "-32659" or "32768". [Assuming 16-bit ints, and
> a %d conversion specifier]
I agree about "-32659". I think there is some question, or at
least an argument can be made, in the case of "32768", where the
object being stored into is an unsigned int rather than an int.
Certainly /the object/ can represent the value 32768. And the
type chocen to do the initial conversion ("the input item [...]
is converted to a type appropriate to the conversion specifier"),
which could be 'long long' for example, also could represent the
value 32768. Note also that the Standard doesn't say what type
is used to do the actual store operation. If (in the example
being discussed) the input item doesn't have a minus sign, is
there any reason an implementation couldn't choose 'unsigned' as
the type for the initial conversion and also as the type to do
the store? Certainly that isn't what most people would expect,
but is there anything in the Standard that actually rules it out?
I'm not aware of anything (although I should add that I haven't
looked much).
An advantage of behavior being undefined is that it leaves open
the possibility that implementations will define some sensible
behavior in some cases. But before we think about changing the
boundary it's important to be sure about exactly which
circumstances /are/ undefined behavior, and which are not.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-11-13 14:32 -0800 |
| Subject | Re: One over another: (*structp).component structp->component |
| Message-ID | <8b45f839-caf3-47af-bc54-7ee43dbd2753@googlegroups.com> |
| In reply to | #75947 |
On Friday, November 13, 2015 at 7:36:56 AM UTC-6, Tim Rentsch wrote: > I think you're misreading the requirements here. Effective type > rules apply to write access as well as read access. The stored > value is being "accessed" - it is being written! Do the effective type rules provide a clean means of "unsetting" the effective type associated with a block of storage? If one wishes to have a malloc-like function which e.g. returns chunks of memory from a pool to code which may use them for arbitrary purposes before returning them to the pool (common in embedded systems) is there a portable way to do that, or should one simply regard C as being totally unsuitable for systems programming except on compilers which promise to enforce that rule only in very narrow circumstances, if at all? > An advantage of behavior being undefined is that it leaves open > the possibility that implementations will define some sensible > behavior in some cases. But before we think about changing the > boundary it's important to be sure about exactly which > circumstances /are/ undefined behavior, and which are not. I wonder when it became fashionable to regard Undefined Behavior not as an opportunity for implementations to define sensible behaviors, but rather as an excuse for compilers to substitute useless behaviors for what would in many cases otherwise been useful behaviors provided by the underlying platform?
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-11-14 12:09 -0800 |
| Subject | Re: One over another: (*structp).component structp->component |
| Message-ID | <kfnfv08pcm9.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #75982 |
supercat@casperkitty.com writes: > On Friday, November 13, 2015 at 7:36:56 AM UTC-6, Tim Rentsch wrote: >> I think you're misreading the requirements here. Effective type >> rules apply to write access as well as read access. The stored >> value is being "accessed" - it is being written! > > Do the effective type rules provide a clean means of "unsetting" > the effective type associated with a block of storage? [snip] FYI, I have a general rule against answering questions in cases where I think the person asking the question is easily capable of answering it themselves.
[toc] | [prev] | [next] | [standalone]
| From | raltbos@xs4all.nl (Richard Bos) |
|---|---|
| Date | 2015-11-17 22:03 +0000 |
| Subject | Re: One over another: (*structp).component structp->component |
| Message-ID | <564ba3fe.25246593@news.xs4all.nl> |
| In reply to | #75982 |
supercat@casperkitty.com wrote: > I wonder when it became fashionable to regard Undefined Behavior not as an > opportunity for implementations to define sensible behaviors, but rather as > an excuse for compilers to substitute useless behaviors for what would in > many cases otherwise been useful behaviors provided by the underlying > platform? I wonder when it became fashionable for men not to wear uranium hats, but rather plutonium codpieces? Richard
[toc] | [prev] | [next] | [standalone]
| From | David Thompson <dave.thompson2@verizon.net> |
|---|---|
| Date | 2015-12-06 07:56 -0500 |
| Subject | Re: One over another: (*structp).component structp->component |
| Message-ID | <s2c86bl8eqq67jrhg0kukc1nqqbjqbg1s8@4ax.com> |
| In reply to | #75015 |
On Thu, 05 Nov 2015 12:50:09 -0800, Keith Thompson <kst-u@mib.org> wrote: > Eric Sosman <esosman@comcast-dot-net.invalid> writes: > > On 11/5/2015 11:25 AM, G G wrote: > [...] > >> [vf]scanf(const char *format, ...) May overflow its arguments. > > > > Not quite sure what they're talking about here: Using the > > "%s" and "%[" without a field width (the gets() problem), or > > providing too few arguments to match the format. Either way, > > I'd say it's a case of danger arising from misuse. > > If you read a number (either integer or floating-point) and the input > has the expected form but represents a value outside the range of > the type, the behavior is undefined. This makes it impossible > to use any of the *scanf functions safely for numeric input. > I believe that's the case even for unsigned integers. > > N1570 7.21.6.2p10: "If this object does not have an appropriate type, > or if the result of the conversion cannot be represented in the object, > the behavior is undefined.". > Nitpick: for integers, _IF_ you only need unsigned input values with maximum strictly less than the greatest power of 8,10,16 not exceeding type_MAX, you can limit the input field _width_ in chars so that any value it can represent (and convert to) cannot be too big. Of course in this case if the user (or other data source) tries to use too big a value this silently changes it, so you might want to %c the _next_ character and if it's (present and) a digit complain about it. (If not but it should be part of the next input, ungetc, even more ugly.) For people who grew up with punched cards, or even fixedwidth fields on 3270s and the like, this even feels comfortingly familiar, lacking only the clanky sound when you reach for keyboard unlock.
[toc] | [prev] | [next] | [standalone]
| From | G G <gdotone@gmail.com> |
|---|---|
| Date | 2015-11-05 09:26 -0800 |
| Subject | Re: One over another: (*structp).component structp->component |
| Message-ID | <8b8500e3-fa8a-4a9a-b992-4bf5d1a9a6a1@googlegroups.com> |
| In reply to | #74979 |
On Thursday, November 5, 2015 at 11:26:02 AM UTC-5, G G wrote:
> Could someone please post the code for strcpy_s?
> As most know I'm learning, and this seems to be
> a function which many seem to be discussing.
>
I found it or a version of it. Because of the copyrighting
I thought I should include it and the rest of its notice.
/*
* Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* The contents of this file constitute Original Code as defined in and
* are subject to the Apple Public Source License Version 1.1 (the
* "License"). You may not use this file except in compliance with the
* License. Please obtain a copy of the License at
* http://www.apple.com/publicsource and read it before using this file.
*
* This Original Code and all software distributed under the License are
* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/* Copyright (c) 1992, 1997 NeXT Software, Inc. All rights reserved.
*
* File: libc/gen/ppc/strcpy.c
*
* This file contains machine dependent code for string copy
*
* HISTORY
* 24-Jan-1997 Umesh Vaishampayan (umeshv@NeXT.com)
* Ported to PPC.
* 24-Nov-92 Derek B Clegg (dclegg@next.com)
* Created.
*/
#import <string.h>
/* XXX This routine should be optimized. */
/* ANSI sez:
* The `strcpy' function copies the string pointed to by `s2' (including
* the terminating null character) into the array pointed to by `s1'.
* If copying takes place between objects that overlap, the behavior
* is undefined.
* The `strcpy' function returns the value of `s1'. [4.11.2.3]
*/
char *
strcpy(char *s1, const char *s2)
{
char *s = s1;
while ((*s++ = *s2++) != 0)
;
return (s1);
}
What difference does overlapping make?
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-11-05 18:06 +0000 |
| Subject | Re: One over another: (*structp).component structp->component |
| Message-ID | <87oaf8z5g3.fsf@bsb.me.uk> |
| In reply to | #74990 |
G G <gdotone@gmail.com> writes:
> On Thursday, November 5, 2015 at 11:26:02 AM UTC-5, G G wrote:
>> Could someone please post the code for strcpy_s?
^^^^^^^^
<snip>
> I found it or a version of it.
You found a version of strcpy which is not what you said you wanted.
<snip>
> char *
> strcpy(char *s1, const char *s2)
> {
> char *s = s1;
> while ((*s++ = *s2++) != 0)
> ;
> return (s1);
> }
That's pretty much the version that's been around since K&R's book.
> What difference does overlapping make?
The fact that the specification says the result is undefined when the
source and the destination overlap means that the implementation is off
the hook. It can do whatever it likes. Step though the execution of
char test[] = "test";
strcpy(test + 1, test);
to see how the code exploits that permission.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | G G <gdotone@gmail.com> |
|---|---|
| Date | 2015-11-05 10:10 -0800 |
| Subject | Re: One over another: (*structp).component structp->component |
| Message-ID | <48eea573-4b96-4512-b17c-24f690c1fd0f@googlegroups.com> |
| In reply to | #74997 |
On Thursday, November 5, 2015 at 1:06:45 PM UTC-5, Ben Bacarisse wrote: > G G <gdotone@gmail.com> writes: > > > On Thursday, November 5, 2015 at 11:26:02 AM UTC-5, G G wrote: > >> Could someone please post the code for strcpy_s? > ^^^^^^^^ > <snip> > > I found it or a version of it. Ben you are right. I posted the wrong code. Sorry.
[toc] | [prev] | [next] | [standalone]
Page 7 of 10 — ← Prev page 1 … 5 6 [7] 8 9 10 Next page →
Back to top | Article view | comp.lang.c
csiph-web