Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #124080 > unrolled thread
| Started by | "Rick C. Hodgin" <rick.c.hodgin@gmail.com> |
|---|---|
| First post | 2017-12-09 16:20 -0800 |
| Last post | 2017-12-24 21:04 -0800 |
| Articles | 20 on this page of 320 — 28 participants |
Back to article view | Back to comp.lang.c
Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-09 16:20 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-10 00:31 +0000
Re: Auto-execute code at exit? gordonb.k2333@burditt.org (Gordon Burditt) - 2017-12-09 20:40 -0600
Re: Auto-execute code at exit? fir <profesor.fir@gmail.com> - 2017-12-10 02:21 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-10 11:50 +0000
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-10 04:19 -0800
Re: Auto-execute code at exit? fir <profesor.fir@gmail.com> - 2017-12-10 04:32 -0800
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-10 04:43 -0800
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-10 05:03 -0800
Who's a troll now? (Was: Auto-execute code at exit?) gazelle@shell.xmission.com (Kenny McCormack) - 2017-12-10 14:01 +0000
Re: Auto-execute code at exit? scott@slp53.sl.home (Scott Lurndal) - 2017-12-11 15:19 +0000
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-11 15:46 +0000
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-11 08:04 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-11 18:35 +0000
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-11 11:09 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-11 20:28 +0000
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-11 12:38 -0800
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-12 09:07 +0100
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-12 11:45 +0000
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-12 13:50 +0100
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-12 19:29 +0000
Re: Auto-execute code at exit? Ian Collins <ian-news@hotmail.com> - 2017-12-13 08:52 +1300
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-12 23:04 +0100
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-12 21:08 +0100
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-12 21:40 +0000
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-12 23:22 +0100
Re: Auto-execute code at exit? supercat@casperkitty.com - 2017-12-12 15:54 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-13 00:11 +0000
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-12 17:38 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-13 10:44 +0000
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-13 03:12 -0800
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-13 10:16 +0100
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-12 09:35 -0800
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-12 20:42 +0100
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-12 09:02 +0100
Re: Auto-execute code at exit? Ian Collins <ian-news@hotmail.com> - 2017-12-12 21:34 +1300
Re: Auto-execute code at exit? scott@slp53.sl.home (Scott Lurndal) - 2017-12-11 18:37 +0000
Re: Auto-execute code at exit? Manfred <noname@invalid.add> - 2017-12-11 19:39 +0100
Re: Auto-execute code at exit? Gordon Burditt <gordon@hammy.burditt.org> - 2017-12-12 20:54 -0600
Re: Auto-execute code at exit? Richard Damon <Richard@Damon-Family.org> - 2017-12-09 19:32 -0500
Re: Auto-execute code at exit? Ian Collins <ian-news@hotmail.com> - 2017-12-10 13:36 +1300
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-09 17:14 -0800
Re: Auto-execute code at exit? Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2017-12-09 21:49 -0700
Re: Auto-execute code at exit? "Pascal J. Bourguignon" <pjb@informatimago.com> - 2017-12-10 11:04 +0100
Re: Auto-execute code at exit? "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2017-12-10 20:22 +0800
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-10 18:10 +0100
Re: Auto-execute code at exit? Melzzzzz <Melzzzzz@zzzzz.com> - 2017-12-10 20:48 +0000
Auto-execute code at exit? mark.bluemel@gmail.com - 2017-12-10 10:59 -0800
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-10 20:37 +0100
Re: Auto-execute code at exit? James Kuyper <jameskuyper@verizon.net> - 2017-12-10 15:58 -0500
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-10 22:59 +0000
Re: Auto-execute code at exit? Melzzzzz <Melzzzzz@zzzzz.com> - 2017-12-11 02:34 +0000
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-11 15:33 +0000
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-11 16:42 +0100
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-11 15:52 +0000
Re: Auto-execute code at exit? gazelle@shell.xmission.com (Kenny McCormack) - 2017-12-11 15:53 +0000
Re: Auto-execute code at exit? "Pascal J. Bourguignon" <pjb@informatimago.com> - 2017-12-11 17:09 +0100
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-11 08:18 -0800
Re: Auto-execute code at exit? "Pascal J. Bourguignon" <pjb@informatimago.com> - 2017-12-11 19:04 +0100
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-11 08:19 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-11 17:26 +0000
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-11 09:40 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-11 18:09 +0000
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-11 11:07 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-11 20:18 +0000
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-11 12:27 -0800
Re: Auto-execute code at exit? Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2017-12-11 13:42 -0700
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-11 12:54 -0800
Re: Auto-execute code at exit? Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2017-12-11 19:34 -0700
Re: Auto-execute code at exit? Melzzzzz <Melzzzzz@zzzzz.com> - 2017-12-11 17:46 +0000
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-11 19:31 +0100
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-11 18:48 +0000
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-12 09:36 +0100
Re: Auto-execute code at exit? gazelle@shell.xmission.com (Kenny McCormack) - 2017-12-11 18:49 +0000
Re: Auto-execute code at exit? scott@slp53.sl.home (Scott Lurndal) - 2017-12-11 20:33 +0000
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-11 12:39 -0800
Re: Auto-execute code at exit? scott@slp53.sl.home (Scott Lurndal) - 2017-12-11 21:22 +0000
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-11 13:25 -0800
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-12 05:45 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-11 21:00 +0000
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-11 13:13 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-11 21:45 +0000
Re: Auto-execute code at exit? Ian Collins <ian-news@hotmail.com> - 2017-12-12 10:46 +1300
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-11 14:04 -0800
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-12 05:42 -0800
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-11 13:53 -0800
Re: Auto-execute code at exit? scott@slp53.sl.home (Scott Lurndal) - 2017-12-11 21:21 +0000
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-11 21:53 +0000
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-11 08:01 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-11 18:00 +0000
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-11 11:01 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-11 20:44 +0000
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-11 12:52 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-11 21:16 +0000
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-11 13:24 -0800
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-12 09:55 +0100
Re: Auto-execute code at exit? Sjouke Burry <burrynulnulfour@ppllaanneett.nnll> - 2017-12-11 22:00 +0100
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-11 21:43 +0000
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-12 09:52 +0100
Re: Auto-execute code at exit? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-12-11 21:41 +0000
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-11 22:33 +0000
Re: Auto-execute code at exit? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-12-12 01:17 +0000
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-12 01:44 +0000
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-12 10:01 +0100
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-12 11:17 +0000
Re: Auto-execute code at exit? mark.bluemel@gmail.com - 2017-12-12 03:40 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-12 12:01 +0000
Re: Auto-execute code at exit? mark.bluemel@gmail.com - 2017-12-12 04:50 -0800
Re: Auto-execute code at exit? Gareth Owen <gwowen@gmail.com> - 2017-12-12 18:33 +0000
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-12 10:37 -0800
Re: Auto-execute code at exit? gazelle@shell.xmission.com (Kenny McCormack) - 2017-12-12 21:43 +0000
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-12 11:31 -0800
Re: Auto-execute code at exit? Gareth Owen <gwowen@gmail.com> - 2017-12-12 20:09 +0000
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-12 13:56 +0100
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-12 19:44 +0000
Re: Auto-execute code at exit? Ian Collins <ian-news@hotmail.com> - 2017-12-13 09:07 +1300
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-12 23:28 +0100
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-13 00:08 +0000
Re: Auto-execute code at exit? "Pascal J. Bourguignon" <pjb@informatimago.com> - 2017-12-13 01:42 +0100
Re: Auto-execute code at exit? Ian Collins <ian-news@hotmail.com> - 2017-12-13 16:35 +1300
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-13 10:55 +0000
Re: Auto-execute code at exit? Melzzzzz <Melzzzzz@zzzzz.com> - 2017-12-13 11:04 +0000
Re: Auto-execute code at exit? Robert Wessel <robertwessel2@yahoo.com> - 2017-12-13 11:45 -0600
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-13 13:36 +0100
Re: Auto-execute code at exit? Ian Collins <ian-news@hotmail.com> - 2017-12-14 07:34 +1300
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-13 03:20 -0800
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-13 11:25 +0100
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-13 11:50 +0000
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-13 14:27 +0100
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-13 14:31 +0000
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-13 16:56 +0100
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-13 19:27 +0000
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-13 21:15 +0100
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-13 22:48 +0000
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-14 07:44 +0100
Re: Auto-execute code at exit? Gareth Owen <gwowen@gmail.com> - 2017-12-14 06:55 +0000
Re: Auto-execute code at exit? mark.bluemel@gmail.com - 2017-12-14 00:32 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-15 00:01 +0000
Re: Auto-execute code at exit? mark.bluemel@gmail.com - 2017-12-15 00:48 -0800
Why post to Usenet? (Was: Auto-execute code at exit?) gazelle@shell.xmission.com (Kenny McCormack) - 2017-12-15 10:51 +0000
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-15 12:18 +0000
Re: Auto-execute code at exit? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-12-15 17:40 +0000
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-15 20:12 +0000
Re: Auto-execute code at exit? David Kleinecke <dkleinecke@gmail.com> - 2017-12-15 12:54 -0800
Re: Auto-execute code at exit? supercat@casperkitty.com - 2017-12-15 13:51 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-16 14:46 +0000
Re: Auto-execute code at exit? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-12-15 23:20 +0000
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-16 00:36 +0100
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-16 01:34 +0000
Re: Auto-execute code at exit? Manfred <noname@invalid.add> - 2017-12-16 20:06 +0100
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-17 17:33 +0100
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-17 21:35 +0000
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-17 15:06 -0800
Re: Auto-execute code at exit? Ian Collins <ian-news@hotmail.com> - 2017-12-18 12:41 +1300
Re: Auto-execute code at exit? Robert Wessel <robertwessel2@yahoo.com> - 2017-12-18 03:36 -0600
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-18 11:51 +0100
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-18 12:02 +0000
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-18 12:43 +0000
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-18 15:07 +0100
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-18 16:07 +0000
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-18 20:50 +0100
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-18 13:57 +0100
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-18 15:36 +0000
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-18 21:04 +0100
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-18 09:08 -0800
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-18 20:51 +0100
Re: Auto-execute code at exit? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-12-18 15:37 +0000
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-18 16:28 +0000
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-18 10:59 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-18 19:35 +0000
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-18 19:55 +0000
Re: Auto-execute code at exit? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-12-18 20:48 +0000
Re: Auto-execute code at exit? supercat@casperkitty.com - 2017-12-18 13:03 -0800
Re: Auto-execute code at exit? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-12-18 21:14 +0000
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-19 00:08 +0000
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-18 16:58 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-19 01:28 +0000
Re: Auto-execute code at exit? Ian Collins <ian-news@hotmail.com> - 2017-12-19 14:35 +1300
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-19 01:45 +0000
Re: Auto-execute code at exit? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-12-19 01:49 +0000
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-19 02:54 +0000
Re: Auto-execute code at exit? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-12-19 14:45 +0000
Re: Auto-execute code at exit? supercat@casperkitty.com - 2017-12-19 07:48 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-19 16:00 +0000
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-19 17:42 +0100
Re: Auto-execute code at exit? scott@slp53.sl.home (Scott Lurndal) - 2017-12-19 17:19 +0000
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-19 09:43 -0800
Re: Auto-execute code at exit? scott@slp53.sl.home (Scott Lurndal) - 2017-12-19 18:57 +0000
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-19 09:33 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-19 18:34 +0000
Re: Auto-execute code at exit? supercat@casperkitty.com - 2017-12-19 11:05 -0800
Re: Auto-execute code at exit? Manfred <noname@invalid.add> - 2017-12-18 21:09 +0100
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-18 20:38 +0000
Re: Auto-execute code at exit? Ian Collins <ian-news@hotmail.com> - 2017-12-19 13:35 +1300
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-19 01:00 +0000
Re: Auto-execute code at exit? Ian Collins <ian-news@hotmail.com> - 2017-12-19 14:04 +1300
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-20 13:42 +0000
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-20 15:52 +0100
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-20 15:42 +0000
Re: Auto-execute code at exit? supercat@casperkitty.com - 2017-12-20 08:16 -0800
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-20 18:25 +0100
Re: Auto-execute code at exit? supercat@casperkitty.com - 2017-12-20 10:48 -0800
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-20 20:43 +0100
Re: Auto-execute code at exit? supercat@casperkitty.com - 2017-12-20 12:44 -0800
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-21 15:18 +0100
Re: Auto-execute code at exit? supercat@casperkitty.com - 2017-12-21 09:45 -0800
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-21 20:08 +0100
Re: Auto-execute code at exit? supercat@casperkitty.com - 2017-12-21 12:33 -0800
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-21 22:42 +0100
Re: Auto-execute code at exit? supercat@casperkitty.com - 2017-12-21 15:20 -0800
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-22 09:57 +0100
Re: Auto-execute code at exit? supercat@casperkitty.com - 2017-12-22 08:21 -0800
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-23 13:32 +0100
Re: Auto-execute code at exit? Gareth Owen <gwowen@gmail.com> - 2017-12-23 19:35 +0000
Re: Auto-execute code at exit? supercat@casperkitty.com - 2017-12-26 12:08 -0800
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-26 12:36 -0800
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-27 10:38 +0100
Re: Auto-execute code at exit? supercat@casperkitty.com - 2017-12-27 08:14 -0800
Re: Auto-execute code at exit? Richard Damon <Richard@Damon-Family.org> - 2017-12-27 09:50 -0500
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-20 12:12 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-20 18:16 +0000
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-20 19:41 +0100
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-20 22:52 +0000
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-20 15:39 -0800
Re: Auto-execute code at exit? Ian Collins <ian-news@hotmail.com> - 2017-12-21 13:02 +1300
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-21 00:50 +0000
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-20 18:22 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-21 12:10 +0000
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-21 13:10 +0000
Re: Auto-execute code at exit? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-12-21 20:55 +0000
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-21 21:37 +0000
Re: Auto-execute code at exit? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-12-22 01:50 +0000
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-22 12:14 +0000
Re: Auto-execute code at exit? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-12-22 17:01 +0000
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-22 17:34 +0000
Re: Auto-execute code at exit? supercat@casperkitty.com - 2017-12-22 09:52 -0800
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-22 12:02 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-22 20:18 +0000
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-22 12:39 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-22 23:10 +0000
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-22 17:05 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-23 02:17 +0000
Re: Auto-execute code at exit? Richard Damon <Richard@Damon-Family.org> - 2017-12-22 22:14 -0500
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-23 14:43 +0100
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-23 14:31 +0100
Re: Auto-execute code at exit? Ian Collins <ian-news@hotmail.com> - 2017-12-24 09:45 +1300
Re: Auto-execute code at exit? Ian Collins <ian-news@hotmail.com> - 2017-12-23 16:28 +1300
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-23 11:23 +0000
Re: Auto-execute code at exit? Richard Damon <Richard@Damon-Family.org> - 2017-12-23 13:24 -0500
Re: Auto-execute code at exit? Ian Collins <ian-news@hotmail.com> - 2017-12-24 09:29 +1300
Re: Auto-execute code at exit? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-12-21 20:57 +0000
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-21 13:11 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-21 21:58 +0000
Re: Auto-execute code at exit? jameskuyper@verizon.net - 2017-12-21 14:03 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-22 01:34 +0000
Re: Auto-execute code at exit? jameskuyper@verizon.net - 2017-12-22 07:55 -0800
Re: Auto-execute code at exit? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-12-22 16:41 +0000
Re: Auto-execute code at exit? "James R. Kuyper" <jameskuyper@verizon.net> - 2017-12-22 12:46 -0500
Re: Auto-execute code at exit? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-12-23 11:57 +0000
Re: Auto-execute code at exit? James Kuyper <jameskuyper@verizon.net> - 2017-12-23 08:12 -0500
Re: Auto-execute code at exit? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-12-23 21:02 +0000
Re: Auto-execute code at exit? James Kuyper <jameskuyper@verizon.net> - 2017-12-23 16:13 -0500
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-23 22:15 +0000
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-23 14:45 -0800
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-23 15:47 -0800
Re: Auto-execute code at exit? James Kuyper <jameskuyper@verizon.net> - 2017-12-23 19:34 -0500
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-24 12:08 +0000
Re: Auto-execute code at exit? Melzzzzz <Melzzzzz@zzzzz.com> - 2017-12-24 12:11 +0000
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-24 12:17 +0000
Re: Auto-execute code at exit? jameskuyper@verizon.net - 2017-12-24 05:49 -0800
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-24 13:06 -0800
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-23 13:51 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-23 22:17 +0000
Re: Auto-execute code at exit? Gareth Owen <gwowen@gmail.com> - 2017-12-22 18:37 +0000
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-22 19:03 +0000
Re: Auto-execute code at exit? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-12-20 17:44 +0000
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-18 17:22 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-19 01:41 +0000
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-19 09:54 +0100
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-19 13:24 +0000
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-19 14:43 +0100
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-19 09:02 -0800
Re: Auto-execute code at exit? Manfred <noname@invalid.add> - 2017-12-18 20:58 +0100
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-18 22:36 +0100
Re: Auto-execute code at exit? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-12-18 20:37 +0000
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-18 09:13 -0800
Re: Auto-execute code at exit? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-12-18 20:51 +0000
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-18 09:03 -0800
Re: Auto-execute code at exit? Gareth Owen <gwowen@gmail.com> - 2017-12-18 19:13 +0000
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-18 11:28 -0800
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-18 10:07 +0100
Re: Auto-execute code at exit? supercat@casperkitty.com - 2017-12-18 07:50 -0800
Re: Auto-execute code at exit? Ian Collins <ian-news@hotmail.com> - 2017-12-16 12:21 +1300
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-15 09:51 +0100
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-14 12:08 +0000
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-14 05:13 -0800
Re: Auto-execute code at exit? Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2017-12-13 09:21 -0700
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-13 19:27 +0100
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-13 15:14 +0000
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-13 17:11 +0100
Re: Auto-execute code at exit? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-12-13 00:29 +0000
Re: Auto-execute code at exit? mark.bluemel@gmail.com - 2017-12-13 00:41 -0800
Re: Auto-execute code at exit? Gareth Owen <gwowen@gmail.com> - 2017-12-14 06:51 +0000
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-14 14:40 +0000
Re: Auto-execute code at exit? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-12-14 17:15 +0000
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-14 18:59 +0000
Re: Auto-execute code at exit? David Brown <david.brown@hesbynett.no> - 2017-12-12 09:48 +0100
Re: Auto-execute code at exit? Melzzzzz <Melzzzzz@zzzzz.com> - 2017-12-11 17:40 +0000
Re: Auto-execute code at exit? Keith Thompson <kst-u@mib.org> - 2017-12-11 10:57 -0800
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-10 13:56 -0800
Re: Auto-execute code at exit? David Kleinecke <dkleinecke@gmail.com> - 2017-12-10 14:09 -0800
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-10 14:18 -0800
Re: Auto-execute code at exit? asetofsymbols@gmail.com - 2017-12-10 14:51 -0800
Re: Auto-execute code at exit? asetofsymbols@gmail.com - 2017-12-23 11:08 -0800
Re: Auto-execute code at exit? asetofsymbols@gmail.com - 2017-12-25 00:49 -0800
Re: Auto-execute code at exit? bartc <bc@freeuk.com> - 2017-12-11 00:29 +0000
Re: Auto-execute code at exit? Gareth Owen <gwowen@gmail.com> - 2017-12-11 18:30 +0000
Re: Auto-execute code at exit? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-12-11 11:09 -0800
Auto-execute code at exit? asetofsymbols@gmail.com - 2017-12-10 15:05 -0800
Re: Auto-execute code at exit? mcheung63@gmail.com - 2017-12-24 21:04 -0800
Page 11 of 16 — ← Prev page 1 … 9 10 [11] 12 13 … 16 Next page →
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-12-20 18:25 +0100 |
| Message-ID | <p1e6eo$q2b$1@dont-email.me> |
| In reply to | #124526 |
On 20/12/17 17:16, supercat@casperkitty.com wrote:
> On Wednesday, December 20, 2017 at 8:52:45 AM UTC-6, David Brown wrote:
>> "-fstrict-aliasing" is already in place when optimisation is enabled at
>> -O2 or higher. (This is all clearly documented in the gcc reference
>> manual). Perhaps you meant "-fno-strict-aliasing", but there is no
>> reason for that to be needed in generated C code.
>
> If the source language supports any type punning constructs which gcc's
> interpretation of the rules doesn't, how could one sensibly and reliably
> translate such a language into efficient C code without requiring use of
> that flag?
gcc's behaviour with "-fstrict-aliasing" is to apply the rules given in
the C standards - and to assume that the programmer understands those
rules and writes their code appropriately. Calling it "gcc's
interpretation" suggests that gcc is picking a non-standard way to look
at aliasing and type punning - it is not.
If the translator program generates C code that is not compatible with
C's rules for aliasing, then it needs to use "-fno-strict-aliasing" with
gcc. That's okay - it is for compiling such code that gcc has this flag
in the first place.
If you don't want to have to use this flag, or if you want to compile
the code on a C compiler that does not have support for this extension
to the C language, you have to generate C code that does not rely on
non-standard type punning. This is not hard to do (you can always use
memcpy), but it might be hard to do in a way that also results in
efficient object code generated from poorer quality compilers. The
answer then is to have macros, conditional compilation,
compiler-dependent headers, flags to the translator program, or
something like that to get the optimal object code from a range of C
compilers, out of your weird source language. Also remember that the
generated C code does not have to be "nice" - it can be full of messy
unions or whatever it takes to be correct, regardless of how it appears.
Alternatively, simply don't write nonsense in the source language.
There are /very/ few occasions when you really want to alias floats and
integers. About the only sane case is for writing software floating
point routines, and you would not be doing that in this new source language.
>
> If code written in the source language was equivalent to:
>
> float foo;
> float test1(int *ip)
> {
> foo+=1.0;
> *ip += 1;
> return foo;
> }
> float test2(float *fp)
> {
> foo+=1.0;
> *((int*)ip) += 1;
> return foo;
> }
>
/Why/ would anybody write stuff like that? Frankly, I am not
particularly bothered how a compiler handles code that is so meaningless.
> but the source language replaced C's aliasing rule with one that allows
> a compiler to assume that an lvalue is used twice will not be accessed by
> outside means unless, between such accesses, both of the following occur:
>
> 1. A pointer of that type is used, and
> 2. A pointer derived from the above is used to access an object
>
> then a compiler for such a language would be allowed to translate test1
> into:
>
> float foo;
> float test1(int * ip)
> {
> register temp = foo+1.0;
> foo=temp;
> *ip += 1; // Could precede previous statement if desired
> return temp;
> }
>
Standard C allows that transformation, as *ip cannot be used to access
foo. You don't need to "replace C's aliasing rule" in any way. C with
gcc's "-fno-strict-aliasing" flag does not allow that transformation.
> Thus allowing the optimization the C89 Standard intended (according to its
> Rationale) to allow, even when using -fno-strict-aliasing. On the other
> hand, I don't see any good way to translate the second function above into
> gcc's -fstrict-aliasing dialect.
>
test2 can have that same transformation. It only makes sense to call
test2 with a pointer that was originally a pointer to int that was
converted to a pointer to float - otherwise converting it to a pointer
to int and accessing through it will be undefined behaviour. But you
are allowed to take a pointer to int, convert it to a pointer to float
for passing to test2, and then converting it (by a cast) back to a
pointer to int will give the same address.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-12-20 10:48 -0800 |
| Message-ID | <9d1a1034-989f-471e-baf7-b582de093017@googlegroups.com> |
| In reply to | #124527 |
On Wednesday, December 20, 2017 at 11:26:04 AM UTC-6, David Brown wrote: > On 20/12/17 17:16, supercat@casperkitty.com wrote: > > On Wednesday, December 20, 2017 at 8:52:45 AM UTC-6, David Brown wrote: > >> "-fstrict-aliasing" is already in place when optimisation is enabled at > >> -O2 or higher. (This is all clearly documented in the gcc reference > >> manual). Perhaps you meant "-fno-strict-aliasing", but there is no > >> reason for that to be needed in generated C code. > > > > If the source language supports any type punning constructs which gcc's > > interpretation of the rules doesn't, how could one sensibly and reliably > > translate such a language into efficient C code without requiring use of > > that flag? > > gcc's behaviour with "-fstrict-aliasing" is to apply the rules given in > the C standards - and to assume that the programmer understands those > rules and writes their code appropriately. Calling it "gcc's > interpretation" suggests that gcc is picking a non-standard way to look > at aliasing and type punning - it is not. It also assumes that a programmer would rather use an implementation that can only support constructs mandated by the Standard, rather than one which isn't so limited. > If the translator program generates C code that is not compatible with > C's rules for aliasing, then it needs to use "-fno-strict-aliasing" with > gcc. That's okay - it is for compiling such code that gcc has this flag > in the first place. My point was that if the source language defines such semantics, a practical would require that its generated language do so as well. The fact that a translator would impose such a requirement does not in any way imply that it should be considered "defective", or "inferior" to one which generates far less efficient code for tools that can't handle anything beyond the subset of Ritchie's Language for which the Standard mandates support.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-12-20 20:43 +0100 |
| Message-ID | <p1eeh5$oev$1@dont-email.me> |
| In reply to | #124531 |
On 20/12/17 19:48, supercat@casperkitty.com wrote: > On Wednesday, December 20, 2017 at 11:26:04 AM UTC-6, David Brown wrote: >> On 20/12/17 17:16, supercat@casperkitty.com wrote: >>> On Wednesday, December 20, 2017 at 8:52:45 AM UTC-6, David Brown wrote: >>>> "-fstrict-aliasing" is already in place when optimisation is enabled at >>>> -O2 or higher. (This is all clearly documented in the gcc reference >>>> manual). Perhaps you meant "-fno-strict-aliasing", but there is no >>>> reason for that to be needed in generated C code. >>> >>> If the source language supports any type punning constructs which gcc's >>> interpretation of the rules doesn't, how could one sensibly and reliably >>> translate such a language into efficient C code without requiring use of >>> that flag? >> >> gcc's behaviour with "-fstrict-aliasing" is to apply the rules given in >> the C standards - and to assume that the programmer understands those >> rules and writes their code appropriately. Calling it "gcc's >> interpretation" suggests that gcc is picking a non-standard way to look >> at aliasing and type punning - it is not. > > It also assumes that a programmer would rather use an implementation that > can only support constructs mandated by the Standard, rather than one which > isn't so limited. If a programmer wants to use implementation-defined behaviour of a particular compiler in C, that's fine. If he/she wants to rely on implementation-defined behaviour that requires specific flags on a specific compiler, that's fine too. But then that compiler and those flags need to be used - the code is not portable, and cannot be expected to work correctly on other compilers. Where things go wrong is if you write code that depends on such behaviour details, then try to use it elsewhere. > >> If the translator program generates C code that is not compatible with >> C's rules for aliasing, then it needs to use "-fno-strict-aliasing" with >> gcc. That's okay - it is for compiling such code that gcc has this flag >> in the first place. > > My point was that if the source language defines such semantics, a practical > would require that its generated language do so as well. No, it would not. To take a simpler example - suppose the source language required that signed integers had two's complement wrapping overflows. You /could/ handle that by translating the source "integer" into C "int" (or other types of appropriate size), and insisting on gcc with the "-fwrapv" flag. Or you could use casts back and forth with unsigned integer types, unions, etc., to get the right behaviour. This would result in somewhat ugly code - but that does not matter in the slightest for such generated C. It would perhaps not be fully portable - relying on the target having two's complement signed integers. But it would be good enough for all practical purposes. Similar things can be done to handle aliasing. > The fact that a > translator would impose such a requirement does not in any way imply that it > should be considered "defective", or "inferior" to one which generates far > less efficient code for tools that can't handle anything beyond the subset > of Ritchie's Language for which the Standard mandates support. > You are so fond of your misconceptions about a language that never existed in the way you think. Let's stick to C, from when it was /defined/ rather than roughly described.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-12-20 12:44 -0800 |
| Message-ID | <b866cf84-ebeb-4bd2-9f8d-d87cb13b6637@googlegroups.com> |
| In reply to | #124532 |
On Wednesday, December 20, 2017 at 1:43:52 PM UTC-6, David Brown wrote:
> On 20/12/17 19:48, supercat@casperkitty.com wrote:
> >> If the translator program generates C code that is not compatible with
> >> C's rules for aliasing, then it needs to use "-fno-strict-aliasing" with
> >> gcc. That's okay - it is for compiling such code that gcc has this flag
> >> in the first place.
> >
> > My point was that if the source language defines such semantics, a practical
> > would require that its generated language do so as well.
>
> No, it would not.
>
> To take a simpler example - suppose the source language required that
> signed integers had two's complement wrapping overflows. You /could/
> handle that by translating the source "integer" into C "int" (or other
> types of appropriate size), and insisting on gcc with the "-fwrapv"
> flag. Or you could use casts back and forth with unsigned integer
> types, unions, etc., to get the right behaviour. This would result in
> somewhat ugly code - but that does not matter in the slightest for such
> generated C. It would perhaps not be fully portable - relying on the
> target having two's complement signed integers. But it would be good
> enough for all practical purposes.
>
> Similar things can be done to handle aliasing.
Unlike the aliasing case, the -fwrapv case could be handled without loss of
efficiency by having generated code use unsigned types for just about
everything but cast to "int" on those occasions where defined semantics would
differ from unsigned type.
I see no way a code translator could handle source-language aliasing on a
target compiler that can't handle aliasing without an efficiency penalty far
greater than that of -fno-strict-aliasing.
Also, the only way gcc and clang can be said to uphold the Standard with
regard to aliasing is by stretching the meanings of some words. Consider
the function:
void clear_effective_type(unsigned char *q)
{
unsigned char temp = *q^1;
*q = temp^1;
}
There's no reason a quality compiler should generally need to generate
instructions that would actually perform a character-type load and store
of *q, but function would have behavior defined as erasing the effective
type of *q unless it "copies the value as an array of character type".
Both gcc and clang treat the above function as a no-op which does not
affect the Effective Type of *q. The only ways in which I can see that
such behavior would be consistent with the Standard would be by
interpreting the "array of character type" exception as applicable to
the above function, or by regarding programs containing the above function
as somehow violating a translation limit.
From what I can tell, both gcc and clang seem to have adopted an aliasing
model that assumes objects' effective type can only be changed by physically
storing data to them, and thus lack any means of handling the semantics
required by the Standard efficiently. Judging from bugzilla, the fact that
those compilers' aliasing models can't handle all the corner cases of the
Standard effectively means the Standard is defective, and there's no reason
compilers should uphold defective parts of the Standard.
> > The fact that a
> > translator would impose such a requirement does not in any way imply that it
> > should be considered "defective", or "inferior" to one which generates far
> > less efficient code for tools that can't handle anything beyond the subset
> > of Ritchie's Language for which the Standard mandates support.
>
> You are so fond of your misconceptions about a language that never
> existed in the way you think. Let's stick to C, from when it was
> /defined/ rather than roughly described.
It was described well enough to be useful and become popular. It was also
well enough described, btw, that the authors of the Standard had enough of
an understanding to recognize that the code given in the Rationale would
have a meaning in the pointer-aliasing case. According to the Rationale,
a described optimization would be "incorrect" [it used that term] if the
pointers aliased, but did not want to forbid optimizations which would be
correct in all situations that were likely to occur. The fact that the
Standard would allow optimizations that would be incorrect in some unlikely
situations does not imply that quality implementations should be blind to
evidence that the situations are, in fact, likely.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-12-21 15:18 +0100 |
| Message-ID | <p1gfr8$vjl$1@dont-email.me> |
| In reply to | #124534 |
On 20/12/17 21:44, supercat@casperkitty.com wrote:
> On Wednesday, December 20, 2017 at 1:43:52 PM UTC-6, David Brown wrote:
>> On 20/12/17 19:48, supercat@casperkitty.com wrote:
>>>> If the translator program generates C code that is not compatible with
>>>> C's rules for aliasing, then it needs to use "-fno-strict-aliasing" with
>>>> gcc. That's okay - it is for compiling such code that gcc has this flag
>>>> in the first place.
>>>
>>> My point was that if the source language defines such semantics, a practical
>>> would require that its generated language do so as well.
>>
>> No, it would not.
>>
>> To take a simpler example - suppose the source language required that
>> signed integers had two's complement wrapping overflows. You /could/
>> handle that by translating the source "integer" into C "int" (or other
>> types of appropriate size), and insisting on gcc with the "-fwrapv"
>> flag. Or you could use casts back and forth with unsigned integer
>> types, unions, etc., to get the right behaviour. This would result in
>> somewhat ugly code - but that does not matter in the slightest for such
>> generated C. It would perhaps not be fully portable - relying on the
>> target having two's complement signed integers. But it would be good
>> enough for all practical purposes.
>>
>> Similar things can be done to handle aliasing.
>
> Unlike the aliasing case, the -fwrapv case could be handled without loss of
> efficiency by having generated code use unsigned types for just about
> everything but cast to "int" on those occasions where defined semantics would
> differ from unsigned type.
>
> I see no way a code translator could handle source-language aliasing on a
> target compiler that can't handle aliasing without an efficiency penalty far
> greater than that of -fno-strict-aliasing.
>
> Also, the only way gcc and clang can be said to uphold the Standard with
> regard to aliasing is by stretching the meanings of some words. Consider
> the function:
>
> void clear_effective_type(unsigned char *q)
> {
> unsigned char temp = *q^1;
> *q = temp^1;
> }
(Please use sensible spacing - "*q ^ 1". As well as making the code
easier to read, it avoids the risk of "clever" newsclients interpreting
it as subscript 1.)
>
> There's no reason a quality compiler should generally need to generate
> instructions that would actually perform a character-type load and store
> of *q, but function would have behavior defined as erasing the effective
> type of *q unless it "copies the value as an array of character type".
> Both gcc and clang treat the above function as a no-op which does not
> affect the Effective Type of *q. The only ways in which I can see that
> such behavior would be consistent with the Standard would be by
> interpreting the "array of character type" exception as applicable to
> the above function, or by regarding programs containing the above function
> as somehow violating a translation limit.
The effective type of an object is metadata tracked by the compiler - it
is not directly connected to the object code generated. The compiler
can skip the load and store without that making any difference to how it
tracks the effective type.
I cannot claim to have studied the effective type sections of the
standards, so hopefully someone who knows them better than I do will
correct me if I am wrong. With that proviso:
An object with a declared type (anything other than an allocated object)
cannot have its effective type changed. The rules in 6.5p6 specify how
to apply a new effective type to an object of undeclared type - i.e., in
space returned by malloc() and related functions. They allow you to
/change/ the effective type - they do not allow you to "erase" it.
>
> From what I can tell, both gcc and clang seem to have adopted an aliasing
> model that assumes objects' effective type can only be changed by physically
> storing data to them, and thus lack any means of handling the semantics
> required by the Standard efficiently. Judging from bugzilla, the fact that
> those compilers' aliasing models can't handle all the corner cases of the
> Standard effectively means the Standard is defective, and there's no reason
> compilers should uphold defective parts of the Standard.
Have you a reference to these bugzilla reports? At this stage, I can't
judge whether the problem is with the standards (this would be a
surprise, since the relevant paragraphs have not changed between C99 and
C11 - if there were a known problem here, surely it would have been
corrected), or with the compiler, or with your interpretation of things.
>
>>> The fact that a
>>> translator would impose such a requirement does not in any way imply that it
>>> should be considered "defective", or "inferior" to one which generates far
>>> less efficient code for tools that can't handle anything beyond the subset
>>> of Ritchie's Language for which the Standard mandates support.
>>
>> You are so fond of your misconceptions about a language that never
>> existed in the way you think. Let's stick to C, from when it was
>> /defined/ rather than roughly described.
>
> It was described well enough to be useful and become popular. It was also
> well enough described, btw, that the authors of the Standard had enough of
> an understanding to recognize that the code given in the Rationale would
> have a meaning in the pointer-aliasing case. According to the Rationale,
> a described optimization would be "incorrect" [it used that term] if the
> pointers aliased, but did not want to forbid optimizations which would be
> correct in all situations that were likely to occur. The fact that the
> Standard would allow optimizations that would be incorrect in some unlikely
> situations does not imply that quality implementations should be blind to
> evidence that the situations are, in fact, likely.
>
You might like to read the introduction to the C99 Rationale to see some
comments about K&R.
The Rationale is /not/ the Standard.
To me, the rationale is quite clear here regarding aliasing. (I am
looking at section 6.5 in the C99 rationale, v5.10). The example is :
int a;
void f( double * b )
{
a = 1;
*b = 2.0;
g(a);
}
It says "again the optimization is incorrect only if b points to a",
regarding changing "g(a)" to "g(1)". "The C89 Committee has decided
that such dubious possibilities need not be allowed for."
Thus a C compiler does not have to consider the possibility of b point
to a - it /can/ optimise to g(1) in this case, and the optimisation is
considered valid and correct. This matches the Standard section 6.5.
It also matches the "proverbs" in the introduction of the Rationale -
"Trust the programmer" and "Make it fast, even if it is not guaranteed
to be portable".
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-12-21 09:45 -0800 |
| Message-ID | <24e64e7d-e227-45ba-9e0d-69ebf635cb77@googlegroups.com> |
| In reply to | #124548 |
On Thursday, December 21, 2017 at 8:18:36 AM UTC-6, David Brown wrote:
> On 20/12/17 21:44, supercat@casperkitty.com wrote:
> > On Wednesday, December 20, 2017 at 1:43:52 PM UTC-6, David Brown wrote:
> >> On 20/12/17 19:48, supercat@casperkitty.com wrote:
> >>>> If the translator program generates C code that is not compatible with
> >>>> C's rules for aliasing, then it needs to use "-fno-strict-aliasing" with
> >>>> gcc. That's okay - it is for compiling such code that gcc has this flag
> >>>> in the first place.
> >>>
> >>> My point was that if the source language defines such semantics, a practical
> >>> would require that its generated language do so as well.
> >>
> >> No, it would not.
> >>
> >> To take a simpler example - suppose the source language required that
> >> signed integers had two's complement wrapping overflows. You /could/
> >> handle that by translating the source "integer" into C "int" (or other
> >> types of appropriate size), and insisting on gcc with the "-fwrapv"
> >> flag. Or you could use casts back and forth with unsigned integer
> >> types, unions, etc., to get the right behaviour. This would result in
> >> somewhat ugly code - but that does not matter in the slightest for such
> >> generated C. It would perhaps not be fully portable - relying on the
> >> target having two's complement signed integers. But it would be good
> >> enough for all practical purposes.
> >>
> >> Similar things can be done to handle aliasing.
> >
> > Unlike the aliasing case, the -fwrapv case could be handled without loss of
> > efficiency by having generated code use unsigned types for just about
> > everything but cast to "int" on those occasions where defined semantics would
> > differ from unsigned type.
> >
> > I see no way a code translator could handle source-language aliasing on a
> > target compiler that can't handle aliasing without an efficiency penalty far
> > greater than that of -fno-strict-aliasing.
> >
> > Also, the only way gcc and clang can be said to uphold the Standard with
> > regard to aliasing is by stretching the meanings of some words. Consider
> > the function:
> >
> > void clear_effective_type(unsigned char *q)
> > {
> > unsigned char temp = *q ^ 1; // adjusted per request
> > *q = temp^1;
> > }
>
> (Please use sensible spacing - "*q ^ 1". As well as making the code
> easier to read, it avoids the risk of "clever" newsclients interpreting
> it as subscript 1.)
>
ok
> > There's no reason a quality compiler should generally need to generate
> > instructions that would actually perform a character-type load and store
> > of *q, but function would have behavior defined as erasing the effective
> > type of *q unless it "copies the value as an array of character type".
> > Both gcc and clang treat the above function as a no-op which does not
> > affect the Effective Type of *q. The only ways in which I can see that
> > such behavior would be consistent with the Standard would be by
> > interpreting the "array of character type" exception as applicable to
> > the above function, or by regarding programs containing the above function
> > as somehow violating a translation limit.
>
> The effective type of an object is metadata tracked by the compiler - it
> is not directly connected to the object code generated. The compiler
> can skip the load and store without that making any difference to how it
> tracks the effective type.
A quality compiler should be able to do that. Unfortunately, both clang
and gcc seem to rely upon stores change the effective type. From what I
can tell, their aliasing model has no concept of an operation that might
change the effective type of an object without writing to it.
> I cannot claim to have studied the effective type sections of the
> standards, so hopefully someone who knows them better than I do will
> correct me if I am wrong. With that proviso:
>
> An object with a declared type (anything other than an allocated object)
> cannot have its effective type changed. The rules in 6.5p6 specify how
> to apply a new effective type to an object of undeclared type - i.e., in
> space returned by malloc() and related functions. They allow you to
> /change/ the effective type - they do not allow you to "erase" it.
The Standard is a bit ambiguous. After:
float test(int *p, float *q, int value)
{
if (*q)
memcpy(p, &value, sizeof value);
return *q;
}
May a compiler assume the Effective Type of *p after the memcpy will always
be "int", or would the Effective Type be "float" if the function had been
invoked:
float f;
test((int*)&f, &f, 123);
that would seem to suggest that the Effective Type of both *p and *q would
be "float" after the memcpy(), but if the compiler processing test() knows
nothing about the caller it would have no way of knowing that the Effective
Type of *p might be "float".
> > From what I can tell, both gcc and clang seem to have adopted an aliasing
> > model that assumes objects' effective type can only be changed by physically
> > storing data to them, and thus lack any means of handling the semantics
> > required by the Standard efficiently. Judging from bugzilla, the fact that
> > those compilers' aliasing models can't handle all the corner cases of the
> > Standard effectively means the Standard is defective, and there's no reason
> > compilers should uphold defective parts of the Standard.
>
> Have you a reference to these bugzilla reports? At this stage, I can't
> judge whether the problem is with the standards (this would be a
> surprise, since the relevant paragraphs have not changed between C99 and
> C11 - if there were a known problem here, surely it would have been
> corrected), or with the compiler, or with your interpretation of things.
I don't have references handy but I could look for them. Thee was a DR
which suggested changing the Effective Type rule to remove the clause which
makes Effective Types effective only until an object gets overwritten, but
the resolution declined to gut the language in such fashion. A better
resolution would have been to recognize a split between a "high-level-only
C" which could revoke most aliasing-related guarantees, and a "low-level C"
which would require compilers to recognize more aliasing constructs than
the Standard would presently mandate.
> You might like to read the introduction to the C99 Rationale to see some
> comments about K&R.
And you might like to read from the introduction to the C89 rationale:
C code can be non-portable. Although it strove to give programmers the
opportunity to write truly portable programs, the Committee did not want
to force programmers into writing portably, to preclude the use of C as a
``high-level assembler'': the ability to write machine-specific code is
one of the strengths of C. It is this principle which largely motivates
drawing the distinction between strictly conforming program and conforming
program (§1.7).
They didn't say "compiler-specific"--they said "machine specific". If there
are three compilers for a given platform (and many platforms have at least
that many), and the only thing they would need to do to allow use of machine
specific features would be to process certain forms of UB as "behave in a
documented fashion characteristic of the environment", I would suggest that
it should be possible to use such features with code that can run on all
three compilers interchangeably. To use the fact that the Standard doesn't
mandate consistent behavior in such cases as justification for not providing
it would be to undermine the purpose of *having* a Standard.
> The Rationale is /not/ the Standard.
True, but the Standard does not claim to define everything that is required
to make something a *quality* implementation of C. The rationale explicitly
recognizes that an implementation could be fully conforming and yet be of
such poor quality as to be useless. The rationale does provide some insight
as to what should be expected of a *quality* implementation.
> To me, the rationale is quite clear here regarding aliasing. (I am
> looking at section 6.5 in the C99 rationale, v5.10). The example is :
>
> int a;
> void f( double * b )
> {
> a = 1;
> *b = 2.0;
> g(a);
> }
>
> It says "again the optimization is incorrect only if b points to a",
> regarding changing "g(a)" to "g(1)". "The C89 Committee has decided
> that such dubious possibilities need not be allowed for."
To what exactly does the phrase "such dubious possibilities" refer? Not
only does the example code contain no hint that aliasing might occur, but
it was constructed in such a way that on most platforms it would be hard
to construct any possible calling code where the aliasing contained
therein would be useful. Note also that "double" is larger than "int",
and that a compiler would be allowed to place anything it liked in the
space following the "int". Had the example instead been something like:
#include <limits.h>
#include <stdio.h>
void test(int *i, short *s, long *p)
{
if (*i)
{
if (sizeof int == sizeof short && INT_MAX==SHRT_MAX)
*s += 1;
else if (sizeof int == sizeof long && INT_MAX==LONG_MAX)
*l += 1;
else
printf("This example isn't applicable to this machine\n");
}
printf("%d", *i);
}
I don't think many committee members would have regarded as even remotely
dubious the possibility that *s or *l might alias *i on machines where
the example would be applicable. Likewise, on platforms where code like
void quick_scale_up_double_exponent(double *d, unsigned amount)
{
((unsigned short*)p)[3] += amt<<4;
}
would scale floating-point numbers in a certain range more quickly than
would be possible using floating-point math, the notion that code like
the above might modify objects of type "double" would be far less dubious
than the notion that it might be intended for use on objects of type
"short".
Is there any indication that the authors of the Standard intended that
quality compilers which are supposed to be suitable for low-level
programming shouldn't be able to handle forms of aliasing that are
useful on their target platforms? Note that the Standard avoids mandating
behaviors that would be useful on some platforms--even many--but not all.
>
> Thus a C compiler does not have to consider the possibility of b point
> to a - it /can/ optimise to g(1) in this case, and the optimisation is
> considered valid and correct. This matches the Standard section 6.5.
I don't think many people would fault a compiler for making the optimization
in that case, given the combined facts that:
1. Nothing within the function would suggest that it makes use of pointers
to int, and
2. On most platforms, code that calls f() may be able to ascertain that
'a' was fortuitously placed before some other object in such a fashion
that using a double* to write both objects might be useful. Since
there would be no way to request such placement, however, it would be
very weird for client code to try to exploit such placement when it
happens to occur.
That does not imply that such optimizations would be reasonable in cases
where neither condition applies.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-12-21 20:08 +0100 |
| Message-ID | <p1h0r2$qs$1@dont-email.me> |
| In reply to | #124570 |
On 21/12/17 18:45, supercat@casperkitty.com wrote:
> On Thursday, December 21, 2017 at 8:18:36 AM UTC-6, David Brown wrote:
>> On 20/12/17 21:44, supercat@casperkitty.com wrote:
>>> On Wednesday, December 20, 2017 at 1:43:52 PM UTC-6, David Brown wrote:
>>>> On 20/12/17 19:48, supercat@casperkitty.com wrote:
>>>>>> If the translator program generates C code that is not compatible with
>>>>>> C's rules for aliasing, then it needs to use "-fno-strict-aliasing" with
>>>>>> gcc. That's okay - it is for compiling such code that gcc has this flag
>>>>>> in the first place.
>>>>>
>>>>> My point was that if the source language defines such semantics, a practical
>>>>> would require that its generated language do so as well.
>>>>
>>>> No, it would not.
>>>>
>>>> To take a simpler example - suppose the source language required that
>>>> signed integers had two's complement wrapping overflows. You /could/
>>>> handle that by translating the source "integer" into C "int" (or other
>>>> types of appropriate size), and insisting on gcc with the "-fwrapv"
>>>> flag. Or you could use casts back and forth with unsigned integer
>>>> types, unions, etc., to get the right behaviour. This would result in
>>>> somewhat ugly code - but that does not matter in the slightest for such
>>>> generated C. It would perhaps not be fully portable - relying on the
>>>> target having two's complement signed integers. But it would be good
>>>> enough for all practical purposes.
>>>>
>>>> Similar things can be done to handle aliasing.
>>>
>>> Unlike the aliasing case, the -fwrapv case could be handled without loss of
>>> efficiency by having generated code use unsigned types for just about
>>> everything but cast to "int" on those occasions where defined semantics would
>>> differ from unsigned type.
>>>
>>> I see no way a code translator could handle source-language aliasing on a
>>> target compiler that can't handle aliasing without an efficiency penalty far
>>> greater than that of -fno-strict-aliasing.
>>>
>>> Also, the only way gcc and clang can be said to uphold the Standard with
>>> regard to aliasing is by stretching the meanings of some words. Consider
>>> the function:
>>>
>>> void clear_effective_type(unsigned char *q)
>>> {
>>> unsigned char temp = *q ^ 1; // adjusted per request
>>> *q = temp^1;
>>> }
>>
>> (Please use sensible spacing - "*q ^ 1". As well as making the code
>> easier to read, it avoids the risk of "clever" newsclients interpreting
>> it as subscript 1.)
>>
> ok
>
Thanks. I think good use of spacing helps clarity in C code, but in
this case it definitely helps clarity of reading with Thunderbird!
>>> There's no reason a quality compiler should generally need to generate
>>> instructions that would actually perform a character-type load and store
>>> of *q, but function would have behavior defined as erasing the effective
>>> type of *q unless it "copies the value as an array of character type".
>>> Both gcc and clang treat the above function as a no-op which does not
>>> affect the Effective Type of *q. The only ways in which I can see that
>>> such behavior would be consistent with the Standard would be by
>>> interpreting the "array of character type" exception as applicable to
>>> the above function, or by regarding programs containing the above function
>>> as somehow violating a translation limit.
>>
>> The effective type of an object is metadata tracked by the compiler - it
>> is not directly connected to the object code generated. The compiler
>> can skip the load and store without that making any difference to how it
>> tracks the effective type.
>
> A quality compiler should be able to do that. Unfortunately, both clang
> and gcc seem to rely upon stores change the effective type. From what I
> can tell, their aliasing model has no concept of an operation that might
> change the effective type of an object without writing to it.
Have you any basis for that claim? For example, if you change that code
slightly so that a load and a store /are/ generated, does that make a
difference to the effective type handling - in a way that you can
clearly see? Otherwise, what you are doing is noting that gcc and clang
eliminate the load and store, and noting that they do not handle the
effective type of *q the way you expect (not that I can see what you
expect here, or how you can tell what the compiler is doing). From that
you are concluding that there is a causation effect - and I don't see
justification for that.
>
>> I cannot claim to have studied the effective type sections of the
>> standards, so hopefully someone who knows them better than I do will
>> correct me if I am wrong. With that proviso:
>>
>> An object with a declared type (anything other than an allocated object)
>> cannot have its effective type changed. The rules in 6.5p6 specify how
>> to apply a new effective type to an object of undeclared type - i.e., in
>> space returned by malloc() and related functions. They allow you to
>> /change/ the effective type - they do not allow you to "erase" it.
>
> The Standard is a bit ambiguous. After:
>
> float test(int *p, float *q, int value)
> {
> if (*q)
> memcpy(p, &value, sizeof value);
> return *q;
> }
>
> May a compiler assume the Effective Type of *p after the memcpy will always
> be "int", or would the Effective Type be "float" if the function had been
> invoked:
>
> float f;
> test((int*)&f, &f, 123);
>
> that would seem to suggest that the Effective Type of both *p and *q would
> be "float" after the memcpy(), but if the compiler processing test() knows
> nothing about the caller it would have no way of knowing that the Effective
> Type of *p might be "float".
If the object pointed to by p is a declared type, its effective type
never changes - even if you memcpy to it from something else.
If it that declared type is not compatible with an int, then accessing
it through an int pointer is undefined.
If it has no declared type (it is allocated memory), then you can memcpy
to it - the effective type will be "int" if *q is non-zero, unchanged
otherwise.
In your example, "f" /always/ has effective type "float" regardless of
what "test" might do. But within "test", the compiler can assume that
*p has effective type "int" after the memcpy - either the function is
called with p pointing to allocated memory, in which case *p gains the
effective type of "int", or it points to something compatible with
"int", or the behaviour is undefined because you are trying to change
the effective type.
>
>>> From what I can tell, both gcc and clang seem to have adopted an aliasing
>>> model that assumes objects' effective type can only be changed by physically
>>> storing data to them, and thus lack any means of handling the semantics
>>> required by the Standard efficiently. Judging from bugzilla, the fact that
>>> those compilers' aliasing models can't handle all the corner cases of the
>>> Standard effectively means the Standard is defective, and there's no reason
>>> compilers should uphold defective parts of the Standard.
>>
>> Have you a reference to these bugzilla reports? At this stage, I can't
>> judge whether the problem is with the standards (this would be a
>> surprise, since the relevant paragraphs have not changed between C99 and
>> C11 - if there were a known problem here, surely it would have been
>> corrected), or with the compiler, or with your interpretation of things.
>
> I don't have references handy but I could look for them. Thee was a DR
> which suggested changing the Effective Type rule to remove the clause which
> makes Effective Types effective only until an object gets overwritten, but
> the resolution declined to gut the language in such fashion. A better
> resolution would have been to recognize a split between a "high-level-only
> C" which could revoke most aliasing-related guarantees, and a "low-level C"
> which would require compilers to recognize more aliasing constructs than
> the Standard would presently mandate.
I'd be happy to see a little clearer explanation in the standard -
perhaps with some examples.
>
>> You might like to read the introduction to the C99 Rationale to see some
>> comments about K&R.
>
> And you might like to read from the introduction to the C89 rationale:
>
> C code can be non-portable. Although it strove to give programmers the
> opportunity to write truly portable programs, the Committee did not want
> to force programmers into writing portably, to preclude the use of C as a
> ``high-level assembler'': the ability to write machine-specific code is
> one of the strengths of C. It is this principle which largely motivates
> drawing the distinction between strictly conforming program and conforming
> program (§1.7).
>
> They didn't say "compiler-specific"--they said "machine specific". If there
> are three compilers for a given platform (and many platforms have at least
> that many), and the only thing they would need to do to allow use of machine
> specific features would be to process certain forms of UB as "behave in a
> documented fashion characteristic of the environment", I would suggest that
> it should be possible to use such features with code that can run on all
> three compilers interchangeably. To use the fact that the Standard doesn't
> mandate consistent behavior in such cases as justification for not providing
> it would be to undermine the purpose of *having* a Standard.
The rationale is written in loose terms - you cannot treat its choice of
words in that way. It is a rough explanation of some of the decisions
in the actual standards - interesting reading, but no more than that.
>
>> The Rationale is /not/ the Standard.
>
> True, but the Standard does not claim to define everything that is required
> to make something a *quality* implementation of C. The rationale explicitly
> recognizes that an implementation could be fully conforming and yet be of
> such poor quality as to be useless. The rationale does provide some insight
> as to what should be expected of a *quality* implementation.
Some insight, yes - requirements, no.
And remember that what people think of as "quality" can vary. For most
people, it involves producing efficient object code when given correct C
code. For some people, it seems to involve giving the results they
expect even the code does not have behaviour defined by the C standards
- and quality compilers can often accommodate them too (like gcc and
clang having "-fno-strict-aliasing" and "-fwrapv" options).
>
>> To me, the rationale is quite clear here regarding aliasing. (I am
>> looking at section 6.5 in the C99 rationale, v5.10). The example is :
>>
>> int a;
>> void f( double * b )
>> {
>> a = 1;
>> *b = 2.0;
>> g(a);
>> }
>>
>> It says "again the optimization is incorrect only if b points to a",
>> regarding changing "g(a)" to "g(1)". "The C89 Committee has decided
>> that such dubious possibilities need not be allowed for."
>
> To what exactly does the phrase "such dubious possibilities" refer?
It refers to taking the address of the "int" "a", casting it to a
"double *", then passing it to function "f". Casting pointers to
different incompatible types is allowed, but very rarely useful - and
correct code should not be made less efficient because such dubious
rarities may be written. And since the compiler does not have to
consider such code being written, it does not have to generate code that
would work if it did such casting - therefore, such aliasing has
undefined behaviour.
> Not
> only does the example code contain no hint that aliasing might occur, but
> it was constructed in such a way that on most platforms it would be hard
> to construct any possible calling code where the aliasing contained
> therein would be useful.
Messed aliasing is unlikely to be very useful - that is why it is
dubious, and why compilers may ignore the possibility.
> Note also that "double" is larger than "int",
> and that a compiler would be allowed to place anything it liked in the
> space following the "int". Had the example instead been something like:
>
> #include <limits.h>
> #include <stdio.h>
>
> void test(int *i, short *s, long *p)
> {
> if (*i)
> {
> if (sizeof int == sizeof short && INT_MAX==SHRT_MAX)
> *s += 1;
> else if (sizeof int == sizeof long && INT_MAX==LONG_MAX)
> *l += 1;
> else
> printf("This example isn't applicable to this machine\n");
> }
> printf("%d", *i);
> }
>
> I don't think many committee members would have regarded as even remotely
> dubious the possibility that *s or *l might alias *i on machines where
> the example would be applicable. Likewise, on platforms where code like
>
> void quick_scale_up_double_exponent(double *d, unsigned amount)
> {
> ((unsigned short*)p)[3] += amt<<4;
> }
>
> would scale floating-point numbers in a certain range more quickly than
> would be possible using floating-point math, the notion that code like
> the above might modify objects of type "double" would be far less dubious
> than the notion that it might be intended for use on objects of type
> "short".
>
> Is there any indication that the authors of the Standard intended that
> quality compilers which are supposed to be suitable for low-level
> programming shouldn't be able to handle forms of aliasing that are
> useful on their target platforms? Note that the Standard avoids mandating
> behaviors that would be useful on some platforms--even many--but not all.
There is every possibility that the authors of the Standard intended to
allow that sort of thing - but they did not say so directly one way or
the other, and I think it is wrong to try to make guesses as to what
they might have meant. However, there is no doubt that compilers can
have extensions and added features - and in particular, code like this
is likely to be found in low-level libraries or compiler support
libraries (such as for software floating point routines) where
compiler-specific coding is the norm. A function like the one above can
easily be made safe in gcc by :
#pragma GCC push_options
#pragma GCC optimize("-fno-strict-aliasing")
void quick_scale_up_double_exponent(double *d, unsigned amount)
{
((unsigned short*)p)[3] += amt<<4;
}
#pragma GCC pop_options
That is the problem solved - in a manner consistent with the Rationale
for implementation-specific code.
>>
>> Thus a C compiler does not have to consider the possibility of b point
>> to a - it /can/ optimise to g(1) in this case, and the optimisation is
>> considered valid and correct. This matches the Standard section 6.5.
>
> I don't think many people would fault a compiler for making the optimization
> in that case, given the combined facts that:
>
> 1. Nothing within the function would suggest that it makes use of pointers
> to int, and
>
> 2. On most platforms, code that calls f() may be able to ascertain that
> 'a' was fortuitously placed before some other object in such a fashion
> that using a double* to write both objects might be useful. Since
> there would be no way to request such placement, however, it would be
> very weird for client code to try to exploit such placement when it
> happens to occur.
>
> That does not imply that such optimizations would be reasonable in cases
> where neither condition applies.
>
A C compiler is not supposed to be a mind reader. It is supposed to
trust the programmer - including trusting him/her to write correct C code.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-12-21 12:33 -0800 |
| Message-ID | <89528a40-c791-4645-8ab9-13d8d74acd77@googlegroups.com> |
| In reply to | #124574 |
On Thursday, December 21, 2017 at 1:08:30 PM UTC-6, David Brown wrote:
> On 21/12/17 18:45, supercat@casperkitty.com wrote:
> > A quality compiler should be able to do that. Unfortunately, both clang
> > and gcc seem to rely upon stores change the effective type. From what I
> > can tell, their aliasing model has no concept of an operation that might
> > change the effective type of an object without writing to it.
>
> Have you any basis for that claim? For example, if you change that code
> slightly so that a load and a store /are/ generated, does that make a
> difference to the effective type handling - in a way that you can
> clearly see?
Yup. If the load and store are generated, they recognize that the Effective
Type has changed. If the compiler can tell that a store would put the same
bit pattern into memory as had just been read, it omits the store and does
not recognize the possibility of the Effective Type having changed. This is
a very consistent behavior which causes both compilers to malfunction in a
wide variety of situations where a store should change the Effective Type of
an object without altering any of the bits stored therein.
> Otherwise, what you are doing is noting that gcc and clang
> eliminate the load and store, and noting that they do not handle the
> effective type of *q the way you expect (not that I can see what you
> expect here, or how you can tell what the compiler is doing). From that
> you are concluding that there is a causation effect - and I don't see
> justification for that.
The behavior is demonstrable and repeatable.
> > The Standard is a bit ambiguous. After:
> >
> > float test(int *p, float *q, int value)
> > {
> > if (*q)
> > memcpy(p, &value, sizeof value);
> > return *q;
> > }
> >
> > May a compiler assume the Effective Type of *p after the memcpy will always
> > be "int", or would the Effective Type be "float" if the function had been
> > invoked:
> >
> > float f;
> > test((int*)&f, &f, 123);
> >
> > that would seem to suggest that the Effective Type of both *p and *q would
> > be "float" after the memcpy(), but if the compiler processing test() knows
> > nothing about the caller it would have no way of knowing that the Effective
> > Type of *p might be "float".
>
> If the object pointed to by p is a declared type, its effective type
> never changes - even if you memcpy to it from something else.
>
> If it that declared type is not compatible with an int, then accessing
> it through an int pointer is undefined.
>
> If it has no declared type (it is allocated memory), then you can memcpy
> to it - the effective type will be "int" if *q is non-zero, unchanged
> otherwise.
>
> In your example, "f" /always/ has effective type "float" regardless of
> what "test" might do. But within "test", the compiler can assume that
> *p has effective type "int" after the memcpy - either the function is
> called with p pointing to allocated memory, in which case *p gains the
> effective type of "int", or it points to something compatible with
> "int", or the behaviour is undefined because you are trying to change
> the effective type.
From the Standard:
"If a value is copied into an object **having no declared type** using
memcpy or memmove..."
In what sense would "memcpy" be "trying to change the Effective Type" of
an object with a declared type?
> > I don't have references handy but I could look for them. Thee was a DR
> > which suggested changing the Effective Type rule to remove the clause which
> > makes Effective Types effective only until an object gets overwritten, but
> > the resolution declined to gut the language in such fashion. A better
> > resolution would have been to recognize a split between a "high-level-only
> > C" which could revoke most aliasing-related guarantees, and a "low-level C"
> > which would require compilers to recognize more aliasing constructs than
> > the Standard would presently mandate.
>
> I'd be happy to see a little clearer explanation in the standard -
> perhaps with some examples.
There's no way to "clarify" things without recognizing a split. The only
sense in which the present rules are "workable" is that any code which would
need to reuse or reinterpret storage in any fashion can simply use
"-fno-strict-aliasing" or equivalent, rendering the rules irrelevant.
> > And you might like to read from the introduction to the C89 rationale:
> >
> > C code can be non-portable. Although it strove to give programmers the
> > opportunity to write truly portable programs, the Committee did not want
> > to force programmers into writing portably, to preclude the use of C as a
> > ``high-level assembler'': the ability to write machine-specific code is
> > one of the strengths of C. It is this principle which largely motivates
> > drawing the distinction between strictly conforming program and conforming
> > program (§1.7).
> >
> > They didn't say "compiler-specific"--they said "machine specific". If there
> > are three compilers for a given platform (and many platforms have at least
> > that many), and the only thing they would need to do to allow use of machine
> > specific features would be to process certain forms of UB as "behave in a
> > documented fashion characteristic of the environment", I would suggest that
> > it should be possible to use such features with code that can run on all
> > three compilers interchangeably. To use the fact that the Standard doesn't
> > mandate consistent behavior in such cases as justification for not providing
> > it would be to undermine the purpose of *having* a Standard.
>
> The rationale is written in loose terms - you cannot treat its choice of
> words in that way. It is a rough explanation of some of the decisions
> in the actual standards - interesting reading, but no more than that.
It also clearly suggests that Ritchie's Language was used in ways beyond
those for which the mandate requires support, and that the ability to
support such usages was recognized as one of the language's strengths.
> >> The Rationale is /not/ the Standard.
> >
> > True, but the Standard does not claim to define everything that is required
> > to make something a *quality* implementation of C. The rationale explicitly
> > recognizes that an implementation could be fully conforming and yet be of
> > such poor quality as to be useless. The rationale does provide some insight
> > as to what should be expected of a *quality* implementation.
>
> Some insight, yes - requirements, no.
>
> And remember that what people think of as "quality" can vary. For most
> people, it involves producing efficient object code when given correct C
> code. For some people, it seems to involve giving the results they
> expect even the code does not have behaviour defined by the C standards
> - and quality compilers can often accommodate them too (like gcc and
> clang having "-fno-strict-aliasing" and "-fwrapv" options).
Different compilers are used for different purposes. A good compiler
for high-end numeric processing may be totally unsuitable for systems
programming. Someone who is doing system programming should not be
expected to write code that is compatible with compilers that are not
suitable for that purpose.
> >> To me, the rationale is quite clear here regarding aliasing. (I am
> >> looking at section 6.5 in the C99 rationale, v5.10). The example is :
> >>
> >> int a;
> >> void f( double * b )
> >> {
> >> a = 1;
> >> *b = 2.0;
> >> g(a);
> >> }
> >>
> >> It says "again the optimization is incorrect only if b points to a",
> >> regarding changing "g(a)" to "g(1)". "The C89 Committee has decided
> >> that such dubious possibilities need not be allowed for."
> >
> > To what exactly does the phrase "such dubious possibilities" refer?
>
> It refers to taking the address of the "int" "a", casting it to a
> "double *", then passing it to function "f". Casting pointers to
> different incompatible types is allowed, but very rarely useful - and
> correct code should not be made less efficient because such dubious
> rarities may be written. And since the compiler does not have to
> consider such code being written, it does not have to generate code that
> would work if it did such casting - therefore, such aliasing has
> undefined behaviour.
In some kinds of code, it would rarely be useful. In others, it would
often be essential. The authors didn't want to compel compilers that are
intended solely for use with the former to expend effort supporting forms
of aliasing that would never be employed in the programs they'd be used
to run, but that doesn't mean they expected that compilers intended for
fields or targets where other forms of aliasing are useful should be
willfully blind to them.
> > Not
> > only does the example code contain no hint that aliasing might occur, but
> > it was constructed in such a way that on most platforms it would be hard
> > to construct any possible calling code where the aliasing contained
> > therein would be useful.
>
> Messed aliasing is unlikely to be very useful - that is why it is
> dubious, and why compilers may ignore the possibility.
Was it coincidence that the example was constructed in such a way that the
likelihood of aliasing being useful would be exceptionally low *even on
platforms and application fields where aliasing would generally be useful*?
If someone says something isn't very useful, and other people put it to
great use, the person who claims it's not useful is wrong.
> > Note also that "double" is larger than "int",
> > and that a compiler would be allowed to place anything it liked in the
> > space following the "int". Had the example instead been something like:
> >
> > #include <limits.h>
> > #include <stdio.h>
> >
> > void test(int *i, short *s, long *p)
> > {
> > if (*i)
> > {
> > if (sizeof int == sizeof short && INT_MAX==SHRT_MAX)
> > *s += 1;
> > else if (sizeof int == sizeof long && INT_MAX==LONG_MAX)
> > *l += 1;
> > else
> > printf("This example isn't applicable to this machine\n");
> > }
> > printf("%d", *i);
> > }
> >
> > I don't think many committee members would have regarded as even remotely
> > dubious the possibility that *s or *l might alias *i on machines where
> > the example would be applicable. Likewise, on platforms where code like
> >
> > void quick_scale_up_double_exponent(double *d, unsigned amount)
> > {
> > ((unsigned short*)p)[3] += amt<<4;
> > }
> >
> > would scale floating-point numbers in a certain range more quickly than
> > would be possible using floating-point math, the notion that code like
> > the above might modify objects of type "double" would be far less dubious
> > than the notion that it might be intended for use on objects of type
> > "short".
> >
> > Is there any indication that the authors of the Standard intended that
> > quality compilers which are supposed to be suitable for low-level
> > programming shouldn't be able to handle forms of aliasing that are
> > useful on their target platforms? Note that the Standard avoids mandating
> > behaviors that would be useful on some platforms--even many--but not all.
>
> There is every possibility that the authors of the Standard intended to
> allow that sort of thing - but they did not say so directly one way or
> the other, and I think it is wrong to try to make guesses as to what
> they might have meant.
The authors of the Standard were certainly aware of such code, and said that
they did wanted to avoid breaking existing code. That would imply a desire
that compilers for platforms and fields where such constructs were being
usefully employed should continue to support them, while those for
platforms and fields where they wouldn't be useful wouldn't be obligated
to support them.
> However, there is no doubt that compilers can
> have extensions and added features - and in particular, code like this
> is likely to be found in low-level libraries or compiler support
> libraries (such as for software floating point routines) where
> compiler-specific coding is the norm. A function like the one above can
> easily be made safe in gcc by :
>
> #pragma GCC push_options
> #pragma GCC optimize("-fno-strict-aliasing")
> void quick_scale_up_double_exponent(double *d, unsigned amount)
> {
> ((unsigned short*)p)[3] += amt<<4;
> }
> #pragma GCC pop_options
>
>
> That is the problem solved - in a manner consistent with the Rationale
> for implementation-specific code.
Requiring different directives on every compiler supporting a target
platform, thus negating the purpose of having a standard.
> A C compiler is not supposed to be a mind reader. It is supposed to
> trust the programmer - including trusting him/her to write correct C code.
No need for mind reading. It would be sufficient to recognize certain
actions that constitute evidence of aliasing, and allow a compiler to
assume aliasing won't occur in places there's no evidence of it. For
most kinds of code where aliasing is useful, local evaluation of evidence
would be sufficient to identify aliasing with few false positives and
fewer false negatives, and most instances of the latter could be fixed by
adding evidence of aliasing.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-12-21 22:42 +0100 |
| Message-ID | <p1h9ri$476$1@dont-email.me> |
| In reply to | #124575 |
On 21/12/17 21:33, supercat@casperkitty.com wrote:
> On Thursday, December 21, 2017 at 1:08:30 PM UTC-6, David Brown wrote:
>> On 21/12/17 18:45, supercat@casperkitty.com wrote:
>>> A quality compiler should be able to do that. Unfortunately, both clang
>>> and gcc seem to rely upon stores change the effective type. From what I
>>> can tell, their aliasing model has no concept of an operation that might
>>> change the effective type of an object without writing to it.
>>
>> Have you any basis for that claim? For example, if you change that code
>> slightly so that a load and a store /are/ generated, does that make a
>> difference to the effective type handling - in a way that you can
>> clearly see?
>
> Yup. If the load and store are generated, they recognize that the Effective
> Type has changed. If the compiler can tell that a store would put the same
> bit pattern into memory as had just been read, it omits the store and does
> not recognize the possibility of the Effective Type having changed. This is
> a very consistent behavior which causes both compilers to malfunction in a
> wide variety of situations where a store should change the Effective Type of
> an object without altering any of the bits stored therein.
>
Please explain why you think the load and store of the same value would
have any effect - regardless of the types or effective types involved.
You are reading a byte from memory, then writing that same byte back
again to the same place. This has no effect.
>> Otherwise, what you are doing is noting that gcc and clang
>> eliminate the load and store, and noting that they do not handle the
>> effective type of *q the way you expect (not that I can see what you
>> expect here, or how you can tell what the compiler is doing). From that
>> you are concluding that there is a causation effect - and I don't see
>> justification for that.
>
> The behavior is demonstrable and repeatable.
>
>>> The Standard is a bit ambiguous. After:
>>>
>>> float test(int *p, float *q, int value)
>>> {
>>> if (*q)
>>> memcpy(p, &value, sizeof value);
>>> return *q;
>>> }
>>>
>>> May a compiler assume the Effective Type of *p after the memcpy will always
>>> be "int", or would the Effective Type be "float" if the function had been
>>> invoked:
>>>
>>> float f;
>>> test((int*)&f, &f, 123);
>>>
>>> that would seem to suggest that the Effective Type of both *p and *q would
>>> be "float" after the memcpy(), but if the compiler processing test() knows
>>> nothing about the caller it would have no way of knowing that the Effective
>>> Type of *p might be "float".
>>
>> If the object pointed to by p is a declared type, its effective type
>> never changes - even if you memcpy to it from something else.
>>
>> If it that declared type is not compatible with an int, then accessing
>> it through an int pointer is undefined.
>>
>> If it has no declared type (it is allocated memory), then you can memcpy
>> to it - the effective type will be "int" if *q is non-zero, unchanged
>> otherwise.
>>
>> In your example, "f" /always/ has effective type "float" regardless of
>> what "test" might do. But within "test", the compiler can assume that
>> *p has effective type "int" after the memcpy - either the function is
>> called with p pointing to allocated memory, in which case *p gains the
>> effective type of "int", or it points to something compatible with
>> "int", or the behaviour is undefined because you are trying to change
>> the effective type.
>
> From the Standard:
>
> "If a value is copied into an object **having no declared type** using
> memcpy or memmove..."
>
> In what sense would "memcpy" be "trying to change the Effective Type" of
> an object with a declared type?
Perhaps it does not. But the compiler can still assume that p points to
an int - either the effective type does not matter (because you are
accessing it as a character pointer), or it is an int, or using the
pointer will be undefined behaviour.
>
>>> I don't have references handy but I could look for them. Thee was a DR
>>> which suggested changing the Effective Type rule to remove the clause which
>>> makes Effective Types effective only until an object gets overwritten, but
>>> the resolution declined to gut the language in such fashion. A better
>>> resolution would have been to recognize a split between a "high-level-only
>>> C" which could revoke most aliasing-related guarantees, and a "low-level C"
>>> which would require compilers to recognize more aliasing constructs than
>>> the Standard would presently mandate.
>>
>> I'd be happy to see a little clearer explanation in the standard -
>> perhaps with some examples.
>
> There's no way to "clarify" things without recognizing a split. The only
> sense in which the present rules are "workable" is that any code which would
> need to reuse or reinterpret storage in any fashion can simply use
> "-fno-strict-aliasing" or equivalent, rendering the rules irrelevant.
Of course there is need to clarify the rules - they are quite obscure as
they stand.
>
>>> And you might like to read from the introduction to the C89 rationale:
>>>
>>> C code can be non-portable. Although it strove to give programmers the
>>> opportunity to write truly portable programs, the Committee did not want
>>> to force programmers into writing portably, to preclude the use of C as a
>>> ``high-level assembler'': the ability to write machine-specific code is
>>> one of the strengths of C. It is this principle which largely motivates
>>> drawing the distinction between strictly conforming program and conforming
>>> program (§1.7).
>>>
>>> They didn't say "compiler-specific"--they said "machine specific". If there
>>> are three compilers for a given platform (and many platforms have at least
>>> that many), and the only thing they would need to do to allow use of machine
>>> specific features would be to process certain forms of UB as "behave in a
>>> documented fashion characteristic of the environment", I would suggest that
>>> it should be possible to use such features with code that can run on all
>>> three compilers interchangeably. To use the fact that the Standard doesn't
>>> mandate consistent behavior in such cases as justification for not providing
>>> it would be to undermine the purpose of *having* a Standard.
>>
>> The rationale is written in loose terms - you cannot treat its choice of
>> words in that way. It is a rough explanation of some of the decisions
>> in the actual standards - interesting reading, but no more than that.
>
> It also clearly suggests that Ritchie's Language was used in ways beyond
> those for which the mandate requires support, and that the ability to
> support such usages was recognized as one of the language's strengths.
>
And that old language is not what we call "C" today - no matter what
strengths it might have had.
>>>> The Rationale is /not/ the Standard.
>>>
>>> True, but the Standard does not claim to define everything that is required
>>> to make something a *quality* implementation of C. The rationale explicitly
>>> recognizes that an implementation could be fully conforming and yet be of
>>> such poor quality as to be useless. The rationale does provide some insight
>>> as to what should be expected of a *quality* implementation.
>>
>> Some insight, yes - requirements, no.
>>
>> And remember that what people think of as "quality" can vary. For most
>> people, it involves producing efficient object code when given correct C
>> code. For some people, it seems to involve giving the results they
>> expect even the code does not have behaviour defined by the C standards
>> - and quality compilers can often accommodate them too (like gcc and
>> clang having "-fno-strict-aliasing" and "-fwrapv" options).
>
> Different compilers are used for different purposes. A good compiler
> for high-end numeric processing may be totally unsuitable for systems
> programming. Someone who is doing system programming should not be
> expected to write code that is compatible with compilers that are not
> suitable for that purpose.
That is possibly true. My experience is that good compilers aim to be
suitable for a wide range of tasks - but that you are expected to use
flags that suit your needs. For example, in system programming with gcc
you might want "-ffast-math" because you are not concerned about tiny
details of floating point implementation - you would rather have
near-perfect results quickly than perfect (according to IEEE) results
slowly. For numerical processing, the opposite is likely to be the
case. But for either type of work, you want lots of features, good
optimisations, extensions, support for different targets, warnings,
etc., - i.e., there is a very large overlap in what is considered
"quality" or "suitable for the purpose".
>
>>>> To me, the rationale is quite clear here regarding aliasing. (I am
>>>> looking at section 6.5 in the C99 rationale, v5.10). The example is :
>>>>
>>>> int a;
>>>> void f( double * b )
>>>> {
>>>> a = 1;
>>>> *b = 2.0;
>>>> g(a);
>>>> }
>>>>
>>>> It says "again the optimization is incorrect only if b points to a",
>>>> regarding changing "g(a)" to "g(1)". "The C89 Committee has decided
>>>> that such dubious possibilities need not be allowed for."
>>>
>>> To what exactly does the phrase "such dubious possibilities" refer?
>>
>> It refers to taking the address of the "int" "a", casting it to a
>> "double *", then passing it to function "f". Casting pointers to
>> different incompatible types is allowed, but very rarely useful - and
>> correct code should not be made less efficient because such dubious
>> rarities may be written. And since the compiler does not have to
>> consider such code being written, it does not have to generate code that
>> would work if it did such casting - therefore, such aliasing has
>> undefined behaviour.
>
> In some kinds of code, it would rarely be useful. In others, it would
> often be essential. The authors didn't want to compel compilers that are
> intended solely for use with the former to expend effort supporting forms
> of aliasing that would never be employed in the programs they'd be used
> to run, but that doesn't mean they expected that compilers intended for
> fields or targets where other forms of aliasing are useful should be
> willfully blind to them.
And thus you have "implementation defined behaviour", and that compilers
are free to provide definitions for things that the standards say are
"undefined behaviour". The rationale says that explicitly. That does
not stop messing with pointer aliasing being "undefined behaviour"
according to the C standards, nor does it mean that a compiler cannot
optimise on the basis of such rules. It means that a compiler can
choose to give such pointer casting and accesses a clearly defined
behaviour if this is something that some people find useful. So that is
/exactly/ what gcc and clang do - they default to the normal needs of
programmers, which is code that does not need weird type aliasing, and
provide options for programmers who /do/ need such behaviour.
>
>>> Not
>>> only does the example code contain no hint that aliasing might occur, but
>>> it was constructed in such a way that on most platforms it would be hard
>>> to construct any possible calling code where the aliasing contained
>>> therein would be useful.
>>
>> Messed aliasing is unlikely to be very useful - that is why it is
>> dubious, and why compilers may ignore the possibility.
>
> Was it coincidence that the example was constructed in such a way that the
> likelihood of aliasing being useful would be exceptionally low *even on
> platforms and application fields where aliasing would generally be useful*?
>
So you think the rule in the standards, and the explanation in the
rationale, was written specifically to promote someone's hidden agenda
here? That sounds like paranoia, or conspiracy theory to me. Have you
considered the possibility that good uses of such aliasing are not, in
fact, particularly common? Or that they are not easy to give in a
simple example?
> If someone says something isn't very useful, and other people put it to
> great use, the person who claims it's not useful is wrong.
I personally have not seen many good uses of such aliasing - and I work
in low-level coding. I have seen a few unnecessary uses of it. And I
have seen a few cases where it could be avoided by slightly more complex
code - code that gcc would optimise efficiently, but that poorer
compilers would not. In those cases there is no way to write code that
is correct according to the rules of C aliasing (and therefore will work
correctly with gcc) and which will also give the desired optimal code on
more limited tools. Such is life for a programmer.
>
>>> Note also that "double" is larger than "int",
>>> and that a compiler would be allowed to place anything it liked in the
>>> space following the "int". Had the example instead been something like:
>>>
>>> #include <limits.h>
>>> #include <stdio.h>
>>>
>>> void test(int *i, short *s, long *p)
>>> {
>>> if (*i)
>>> {
>>> if (sizeof int == sizeof short && INT_MAX==SHRT_MAX)
>>> *s += 1;
>>> else if (sizeof int == sizeof long && INT_MAX==LONG_MAX)
>>> *l += 1;
>>> else
>>> printf("This example isn't applicable to this machine\n");
>>> }
>>> printf("%d", *i);
>>> }
>>>
>>> I don't think many committee members would have regarded as even remotely
>>> dubious the possibility that *s or *l might alias *i on machines where
>>> the example would be applicable. Likewise, on platforms where code like
>>>
>>> void quick_scale_up_double_exponent(double *d, unsigned amount)
>>> {
>>> ((unsigned short*)p)[3] += amt<<4;
>>> }
>>>
>>> would scale floating-point numbers in a certain range more quickly than
>>> would be possible using floating-point math, the notion that code like
>>> the above might modify objects of type "double" would be far less dubious
>>> than the notion that it might be intended for use on objects of type
>>> "short".
>>>
>>> Is there any indication that the authors of the Standard intended that
>>> quality compilers which are supposed to be suitable for low-level
>>> programming shouldn't be able to handle forms of aliasing that are
>>> useful on their target platforms? Note that the Standard avoids mandating
>>> behaviors that would be useful on some platforms--even many--but not all.
>>
>> There is every possibility that the authors of the Standard intended to
>> allow that sort of thing - but they did not say so directly one way or
>> the other, and I think it is wrong to try to make guesses as to what
>> they might have meant.
>
> The authors of the Standard were certainly aware of such code, and said that
> they did wanted to avoid breaking existing code. That would imply a desire
> that compilers for platforms and fields where such constructs were being
> usefully employed should continue to support them, while those for
> platforms and fields where they wouldn't be useful wouldn't be obligated
> to support them.
>
>> However, there is no doubt that compilers can
>> have extensions and added features - and in particular, code like this
>> is likely to be found in low-level libraries or compiler support
>> libraries (such as for software floating point routines) where
>> compiler-specific coding is the norm. A function like the one above can
>> easily be made safe in gcc by :
>>
>> #pragma GCC push_options
>> #pragma GCC optimize("-fno-strict-aliasing")
>> void quick_scale_up_double_exponent(double *d, unsigned amount)
>> {
>> ((unsigned short*)p)[3] += amt<<4;
>> }
>> #pragma GCC pop_options
>>
>>
>> That is the problem solved - in a manner consistent with the Rationale
>> for implementation-specific code.
>
> Requiring different directives on every compiler supporting a target
> platform, thus negating the purpose of having a standard.
Implementation-dependent code - as you would find in such low-level
libraries - can freely use implementation-dependent features and
directives in order to get more efficient code. That is the /point/ of
writing implementation-dependent code.
>
>> A C compiler is not supposed to be a mind reader. It is supposed to
>> trust the programmer - including trusting him/her to write correct C code.
>
> No need for mind reading. It would be sufficient to recognize certain
> actions that constitute evidence of aliasing, and allow a compiler to
> assume aliasing won't occur in places there's no evidence of it. For
> most kinds of code where aliasing is useful, local evaluation of evidence
> would be sufficient to identify aliasing with few false positives and
> fewer false negatives, and most instances of the latter could be fixed by
> adding evidence of aliasing.
>
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-12-21 15:20 -0800 |
| Message-ID | <5c8fa12d-6153-464e-aaa4-637bf404ecac@googlegroups.com> |
| In reply to | #124580 |
On Thursday, December 21, 2017 at 3:42:18 PM UTC-6, David Brown wrote:
> On 21/12/17 21:33, supercat@casperkitty.com wrote:
> Please explain why you think the load and store of the same value would
> have any effect - regardless of the types or effective types involved.
> You are reading a byte from memory, then writing that same byte back
> again to the same place. This has no effect.
Storing a value to an object with a given type should set the Effective Type
of that object without regard for whether the storage occupied thereby might
happen to already hold the same bit pattern. To suggest otherwise would be
to require that any code wanting to use storage as a new type must write two
different values, lest the first write happen to put a bit pattern that the
compiler can determine matches what's already there.
Interestingly, given:
void clear_effective_type(unsigned char *q)
{
unsigned char temp = *q^1;
*q = temp; // Added line
*q = temp^1;
}
int test1(int *p, float *q, unsigned char **pp)
{
if (*p)
{
*q = 1.0;
for (int i=0; i<4; i++)
clear_effective_type(pp[i]);
}
return *p;
}
int test2(void*p)
{
float *fp = p;
int *ip = p;
unsigned char *cp = p;
*ip = 1;
return test1(ip,fp,&cp);
}
adding the write of "temp" into "clear_effective_type" causes gcc to
generate code for test2 that returns a constant 1065353216 rather than
1 (as it should), but does not fix the code for test1 even though the
first write to *q within clear_effective_type should definitely change
the value stored in whatever object *q is part of.
> > In what sense would "memcpy" be "trying to change the Effective Type" of
> > an object with a declared type?
> Perhaps it does not. But the compiler can still assume that p points to
> an int - either the effective type does not matter (because you are
> accessing it as a character pointer), or it is an int, or using the
> pointer will be undefined behaviour.
If the Effective Type of the object remains whatever it was in calling
code the compiler knows nothing about, then a compiler would generally be
required to treat the memcpy() as leaving the object with no effective
type--a semantically useful behavior given the lack of any other standard
means of copying bits in type-agnostic fashion, but one which should be
true in all cases if it's going to be true in the general case where the
compiler knows nothing about the destination object.
> > There's no way to "clarify" things without recognizing a split. The only
> > sense in which the present rules are "workable" is that any code which would
> > need to reuse or reinterpret storage in any fashion can simply use
> > "-fno-strict-aliasing" or equivalent, rendering the rules irrelevant.
>
> Of course there is need to clarify the rules - they are quite obscure as
> they stand.
If the Standard were to recognize a split, then it could easily define a
clear and simple set of rules which fits the needs of low-level programming,
and a different clear and simple set which fits the needs of high-end number
crunching compilers. Otherwise, the only way to make a set of rules that
can pretend to satisfy both needs is to make rules so obscure that nobody
really knows what they say.
> > It also clearly suggests that Ritchie's Language was used in ways beyond
> > those for which the mandate requires support, and that the ability to
> > support such usages was recognized as one of the language's strengths.
>
> And that old language is not what we call "C" today - no matter what
> strengths it might have had.
What would you suggest as a concise and clear retronym for the language that
is suitable for systems programming use?
> > In some kinds of code, it would rarely be useful. In others, it would
> > often be essential. The authors didn't want to compel compilers that are
> > intended solely for use with the former to expend effort supporting forms
> > of aliasing that would never be employed in the programs they'd be used
> > to run, but that doesn't mean they expected that compilers intended for
> > fields or targets where other forms of aliasing are useful should be
> > willfully blind to them.
>
> And thus you have "implementation defined behaviour", and that compilers
> are free to provide definitions for things that the standards say are
> "undefined behaviour". The rationale says that explicitly. That does
> not stop messing with pointer aliasing being "undefined behaviour"
> according to the C standards, nor does it mean that a compiler cannot
> optimise on the basis of such rules. It means that a compiler can
> choose to give such pointer casting and accesses a clearly defined
> behaviour if this is something that some people find useful. So that is
> /exactly/ what gcc and clang do - they default to the normal needs of
> programmers, which is code that does not need weird type aliasing, and
> provide options for programmers who /do/ need such behaviour.
The authors of the Standard did not make any particular effort to classify
as "implementation-defined" all actions for which quality implementations
should define a behavior when practical. Classifying behaviors as UB was
an invitation for compiler writers to exercise judgment to decide what
actions should most appropriately behave in "a documented fashion
characteristic of the environment".
> > Was it coincidence that the example was constructed in such a way that the
> > likelihood of aliasing being useful would be exceptionally low *even on
> > platforms and application fields where aliasing would generally be useful*?
>
> So you think the rule in the standards, and the explanation in the
> rationale, was written specifically to promote someone's hidden agenda
> here? That sounds like paranoia, or conspiracy theory to me. Have you
> considered the possibility that good uses of such aliasing are not, in
> fact, particularly common? Or that they are not easy to give in a
> simple example?
I think that what probably happened is that the Committee agreed that there
were some cases where compilers should be allowed to assume that aliasing
would not occur, and there were some cases where they should not be allowed
to assume that. Since the Standard makes no effort to mandate that
implementations do everything necessary to make them suitable for any
particular purpose, the authors presumably figured that people writing
compilers for various purposes could support the aliasing patterns required
thereby.
> > If someone says something isn't very useful, and other people put it to
> > great use, the person who claims it's not useful is wrong.
>
> I personally have not seen many good uses of such aliasing - and I work
> in low-level coding. I have seen a few unnecessary uses of it. And I
> have seen a few cases where it could be avoided by slightly more complex
> code - code that gcc would optimise efficiently, but that poorer
> compilers would not. In those cases there is no way to write code that
> is correct according to the rules of C aliasing (and therefore will work
> correctly with gcc) and which will also give the desired optimal code on
> more limited tools. Such is life for a programmer.
> > Requiring different directives on every compiler supporting a target
> > platform, thus negating the purpose of having a standard.
>
> Implementation-dependent code - as you would find in such low-level
> libraries - can freely use implementation-dependent features and
> directives in order to get more efficient code. That is the /point/ of
> writing implementation-dependent code.
The point is that if I want to write e.g. a "bare-metal" embedded networking
library for the Z80, or 68000, or some other common processor, such a
library should be dependent upon the networking hardware, such code should
need to know what kind of processor it's running on, but shouldn't need
to care whether it's being processed with a compiler from Introl, or gnu,
or Hi-Tech, or someone else. If the authors of compilers targeting
particular platforms were able to make them compatible with each other in
the days before the Standard, is there any reason existence of the Standard
should make them less compatible?
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-12-22 09:57 +0100 |
| Message-ID | <p1ihd4$6ig$1@dont-email.me> |
| In reply to | #124585 |
On 22/12/17 00:20, supercat@casperkitty.com wrote:
> On Thursday, December 21, 2017 at 3:42:18 PM UTC-6, David Brown wrote:
>> On 21/12/17 21:33, supercat@casperkitty.com wrote:
>> Please explain why you think the load and store of the same value would
>> have any effect - regardless of the types or effective types involved.
>> You are reading a byte from memory, then writing that same byte back
>> again to the same place. This has no effect.
>
> Storing a value to an object with a given type should set the Effective Type
> of that object without regard for whether the storage occupied thereby might
> happen to already hold the same bit pattern.
Nonsense.
You seem to be misunderstanding the relationship between logical,
high-level operations (such as tracking effective types) and physical
operations on the processor. The C compiler and optimisations revolve
around the "as if" rule. Perhaps /logically/ or in an abstract sense,
the code should read from memory and write the value back out again -
but there is certainly no reason why the compiler should generate code
to do so, and certainly it will not affect the logic of the code or how
the compiler views it.
Equally, the compiler is free to have additional loads and stores not
specified in the code, and these cannot affect the code logic, effective
types, or anything else. (Compilers /do/ make such extra loads and
stores for optimisation purposes.)
> To suggest otherwise would be
> to require that any code wanting to use storage as a new type must write two
> different values, lest the first write happen to put a bit pattern that the
> compiler can determine matches what's already there.
>
> Interestingly, given:
>
> void clear_effective_type(unsigned char *q)
> {
> unsigned char temp = *q^1;
> *q = temp; // Added line
> *q = temp^1;
> }
This will be correctly compiled to a single return instruction.
Whatever your ideas about its effect on effective type might be, it
should generate no code.
> int test1(int *p, float *q, unsigned char **pp)
> {
> if (*p)
> {
> *q = 1.0;
> for (int i=0; i<4; i++)
> clear_effective_type(pp[i]);
> }
> return *p;
> }
> int test2(void*p)
> {
> float *fp = p;
> int *ip = p;
> unsigned char *cp = p;
> *ip = 1;
> return test1(ip,fp,&cp);
> }
I am sorry, I can't figure out what this jumble is supposed to do.
Maybe I haven't had enough coffee yet, but I can see that it has
undefined behaviour (you are accessing 4 elements of an array of
unsigned char pointers via pp, but passing it only a single element).
>
> adding the write of "temp" into "clear_effective_type" causes gcc to
> generate code for test2 that returns a constant 1065353216 rather than
> 1 (as it should), but does not fix the code for test1 even though the
> first write to *q within clear_effective_type should definitely change
> the value stored in whatever object *q is part of.
>
It has undefined behaviour - there is no "correct" result.
>>> In what sense would "memcpy" be "trying to change the Effective Type" of
>>> an object with a declared type?
>> Perhaps it does not. But the compiler can still assume that p points to
>> an int - either the effective type does not matter (because you are
>> accessing it as a character pointer), or it is an int, or using the
>> pointer will be undefined behaviour.
>
> If the Effective Type of the object remains whatever it was in calling
> code the compiler knows nothing about, then a compiler would generally be
> required to treat the memcpy() as leaving the object with no effective
> type--a semantically useful behavior given the lack of any other standard
> means of copying bits in type-agnostic fashion, but one which should be
> true in all cases if it's going to be true in the general case where the
> compiler knows nothing about the destination object.
>
>>> There's no way to "clarify" things without recognizing a split. The only
>>> sense in which the present rules are "workable" is that any code which would
>>> need to reuse or reinterpret storage in any fashion can simply use
>>> "-fno-strict-aliasing" or equivalent, rendering the rules irrelevant.
>>
>> Of course there is need to clarify the rules - they are quite obscure as
>> they stand.
>
> If the Standard were to recognize a split, then it could easily define a
> clear and simple set of rules which fits the needs of low-level programming,
> and a different clear and simple set which fits the needs of high-end number
> crunching compilers. Otherwise, the only way to make a set of rules that
> can pretend to satisfy both needs is to make rules so obscure that nobody
> really knows what they say.
I am sorry, I just can't figure out what you are trying to say. Again,
it could be lack of coffee - but it could also be that you don't know
how to write in sentences.
It is quite possible that you have a good point in here somewhere. I
think it is unlikely that you are right but that the C standards
committee and the gcc developers and the clang developers are all wrong.
But I can't say I am an expert on the concept of "effective types" - it
simply has not been an issue in anything I have done. That comes from
three things, I think. First, I don't write nonsense that converts
pointers back and forth between float pointers and integer pointers like
this - if I needed to do something similar, I have unions, memcpy, and
possibly volatile. Secondly, I rarely use allocated memory - all my
data has declared types, and they are accessed only as those types.
Thirdly, if I /do/ need to do something funny, such as making my own
dynamic memory allocation system, I can use implementation-specific
features in that kind of code to be sure of getting what I want.
Perhaps you want to re-think your point here, and write a new post
explaining it clearly? Maybe you want example functions that make
sense, have sensible names, are tested, and have a possible use? If we
can have a thread going that involves other people, I think this could
be an interesting topic and an opportunity for learning. But at the
moment, I don't believe we are getting very far.
(For the record, I am mostly happy with 6.5p7 regarding which objects
may be aliased. However, I would have preferred that integer types with
the same size and representation could alias as well. So typically
"int" and "long" would alias, or "long" and "long long". But the
current rules here are consistent with the type compatibility rules, and
these in turn help enforce a consistency in types that is relevant for
portability.)
>
>>> It also clearly suggests that Ritchie's Language was used in ways beyond
>>> those for which the mandate requires support, and that the ability to
>>> support such usages was recognized as one of the language's strengths.
>>
>> And that old language is not what we call "C" today - no matter what
>> strengths it might have had.
>
> What would you suggest as a concise and clear retronym for the language that
> is suitable for systems programming use?
I use "C" for systems programming. I don't use Ritchie's language, or
K&R C, or any other pre-C language. Until recently I used C99 - now I
usually use C11. Most of my code is pure "standard" C - or at least,
/could/ be pure standard C (with gcc extensions for neater, clearer,
more efficient or easier checked code - but not needed for correctness).
A fair amount relies on widely portable implementation-specific
features, such as the existence of uint8_t. A small amount is
compiler-specific, and of course interaction with hardware is
target-specific. My code works correctly (to my knowledge) and
efficiently regardless of compiler settings - including
"-fstrict-aliasing", "-fno-wrapv", optimisation flags, etc.
So if you can't use modern C and modern tools to do systems programming,
then either don't do system programming, or dig out your open reel tapes
and borrow a dinosaur from a museum.
>
>>> In some kinds of code, it would rarely be useful. In others, it would
>>> often be essential. The authors didn't want to compel compilers that are
>>> intended solely for use with the former to expend effort supporting forms
>>> of aliasing that would never be employed in the programs they'd be used
>>> to run, but that doesn't mean they expected that compilers intended for
>>> fields or targets where other forms of aliasing are useful should be
>>> willfully blind to them.
>>
>> And thus you have "implementation defined behaviour", and that compilers
>> are free to provide definitions for things that the standards say are
>> "undefined behaviour". The rationale says that explicitly. That does
>> not stop messing with pointer aliasing being "undefined behaviour"
>> according to the C standards, nor does it mean that a compiler cannot
>> optimise on the basis of such rules. It means that a compiler can
>> choose to give such pointer casting and accesses a clearly defined
>> behaviour if this is something that some people find useful. So that is
>> /exactly/ what gcc and clang do - they default to the normal needs of
>> programmers, which is code that does not need weird type aliasing, and
>> provide options for programmers who /do/ need such behaviour.
>
> The authors of the Standard did not make any particular effort to classify
> as "implementation-defined" all actions for which quality implementations
> should define a behavior when practical. Classifying behaviors as UB was
> an invitation for compiler writers to exercise judgment to decide what
> actions should most appropriately behave in "a documented fashion
> characteristic of the environment".
No. Again, you are imagining what you /think/ the authors meant -
without any kind of justification (other than a claim they were lazy).
Where they thought it was important that compiler writers had some
freedom but that there should be specific, documented behaviour, they
wrote "implementation-defined behaviour". Where they thought compiler
writers could have more freedom and it is unlikely there would be use
for a particular result, they wrote "undefined behaviour". And they
made it clear that compiler writers /could/ provide documented behaviour
for cases that are labelled "undefined behaviour", but they certainly
did not have to do so.
>
>>> Was it coincidence that the example was constructed in such a way that the
>>> likelihood of aliasing being useful would be exceptionally low *even on
>>> platforms and application fields where aliasing would generally be useful*?
>>
>> So you think the rule in the standards, and the explanation in the
>> rationale, was written specifically to promote someone's hidden agenda
>> here? That sounds like paranoia, or conspiracy theory to me. Have you
>> considered the possibility that good uses of such aliasing are not, in
>> fact, particularly common? Or that they are not easy to give in a
>> simple example?
>
> I think that what probably happened is that the Committee agreed that there
> were some cases where compilers should be allowed to assume that aliasing
> would not occur, and there were some cases where they should not be allowed
> to assume that. Since the Standard makes no effort to mandate that
> implementations do everything necessary to make them suitable for any
> particular purpose, the authors presumably figured that people writing
> compilers for various purposes could support the aliasing patterns required
> thereby.
You mean like compiler writers offering "-fno-strict-aliasing" to people
who want different aliasing rules from the standard? That would be a
novel idea - if only the gcc and clang authors had done that, we
wouldn't have to complain about them and how evil they are!
>
>>> If someone says something isn't very useful, and other people put it to
>>> great use, the person who claims it's not useful is wrong.
>>
>> I personally have not seen many good uses of such aliasing - and I work
>> in low-level coding. I have seen a few unnecessary uses of it. And I
>> have seen a few cases where it could be avoided by slightly more complex
>> code - code that gcc would optimise efficiently, but that poorer
>> compilers would not. In those cases there is no way to write code that
>> is correct according to the rules of C aliasing (and therefore will work
>> correctly with gcc) and which will also give the desired optimal code on
>> more limited tools. Such is life for a programmer.
>
>>> Requiring different directives on every compiler supporting a target
>>> platform, thus negating the purpose of having a standard.
>>
>> Implementation-dependent code - as you would find in such low-level
>> libraries - can freely use implementation-dependent features and
>> directives in order to get more efficient code. That is the /point/ of
>> writing implementation-dependent code.
>
> The point is that if I want to write e.g. a "bare-metal" embedded networking
> library for the Z80, or 68000, or some other common processor, such a
> library should be dependent upon the networking hardware, such code should
> need to know what kind of processor it's running on, but shouldn't need
> to care whether it's being processed with a compiler from Introl, or gnu,
> or Hi-Tech, or someone else. If the authors of compilers targeting
> particular platforms were able to make them compatible with each other in
> the days before the Standard, is there any reason existence of the Standard
> should make them less compatible?
>
Whatever you believe the standard authors /meant/ to write, whatever you
believe early tools claimed to do, whatever you believe to be a utopian
ideal of compilers - the reality is that different compilers are different.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-12-22 08:21 -0800 |
| Message-ID | <46628015-62fa-4003-92d5-afcbf99a2ec3@googlegroups.com> |
| In reply to | #124588 |
On Friday, December 22, 2017 at 2:57:25 AM UTC-6, David Brown wrote:
> On 22/12/17 00:20, supercat@casperkitty.com wrote:
> > Storing a value to an object with a given type should set the Effective Type
> > of that object without regard for whether the storage occupied thereby might
> > happen to already hold the same bit pattern.
>
> Nonsense.
>
> You seem to be misunderstanding the relationship between logical,
> high-level operations (such as tracking effective types) and physical
> operations on the processor. The C compiler and optimisations revolve
> around the "as if" rule. Perhaps /logically/ or in an abstract sense,
> the code should read from memory and write the value back out again -
> but there is certainly no reason why the compiler should generate code
> to do so, and certainly it will not affect the logic of the code or how
> the compiler views it.
>
> Equally, the compiler is free to have additional loads and stores not
> specified in the code, and these cannot affect the code logic, effective
> types, or anything else. (Compilers /do/ make such extra loads and
> stores for optimisation purposes.)
You're sorta making my point. The fact that writing an object sets the
Effective Type of the storage occupied is unrelated to whether or not a
physical store operation would be required. Both gcc and clang, however,
tend to presume that in cases where the physical store operation could be
omitted there is no effect on the Effective Type.
> > To suggest otherwise would be
> > to require that any code wanting to use storage as a new type must write two
> > different values, lest the first write happen to put a bit pattern that the
> > compiler can determine matches what's already there.
> >
> > Interestingly, given:
> >
> > void clear_effective_type(unsigned char *q)
> > {
> > unsigned char temp = *q^1;
> > *q = temp; // Added line
> > *q = temp^1;
> > }
>
> This will be correctly compiled to a single return instruction.
> Whatever your ideas about its effect on effective type might be, it
> should generate no code.
Indeed. It must, however, generate whatever metadata would be required
to ensure that any object which might be aliased by the passed-in char
pointer will have its Effective Type erased, regardless of whether or not
any physical write instructions are generated.
> > If the Standard were to recognize a split, then it could easily define a
> > clear and simple set of rules which fits the needs of low-level programming,
> > and a different clear and simple set which fits the needs of high-end number
> > crunching compilers. Otherwise, the only way to make a set of rules that
> > can pretend to satisfy both needs is to make rules so obscure that nobody
> > really knows what they say.
>
> I am sorry, I just can't figure out what you are trying to say. Again,
> it could be lack of coffee - but it could also be that you don't know
> how to write in sentences.
The existing rules preclude what would be useful optimizations in some
kinds of programs, but are insufficient to define all the behaviors
needed in other kinds. Recognizing that different kinds of programs
should use different rules would make it possible to define rules that
better fit each kind of program.
Consider, for example, the function:
void test(int *ip, float *fp, int mode)
{
*ip = 1;
*fp = 1.0f;
if (mode)
*ip = 1;
}
If the *ip and *fp both identify the same allocated storage, the function
could have two different defined behaviors depending upon the value of
"mode", since whichever write occurs last would set the Effective Type.
If the effect of setting the Effective Type of storage were permanent, then
a compiler could safely assume the pointers won't alias, and then optimize
out the "if" test. In fact, gcc generates code equivalent to:
void test(int *ip, float *fp, int mode)
{
*fp = 1.0f;
*ip = 1;
}
despite the fact that the Standard doesn't allow it. If the function were
called by a program that will never need to recycle storage as different
types within its lifetime, such an optimization would be useful, and rather
than mandating that gcc produce less efficient code here, I think it would
be helpful to recognize a dialect where that optimization would be
legitimate.
There are other kinds of programs, however, which could not be written
effectively without being able to reuse storage as different types. Since
freestanding implementations aren't required to supply malloc(), and often
run on machines with rather limited RAM, it's often necessary to implement
memory-management code in C which can take a block of storage and make
chunks available for various purposes at different times. If a program
running on a system with 8K RAM needs 1200 doubles at some point in its
execution, and 2400 shorts at some other point, such a need could be
fulfilled if it can recycle storage, but not if it can't.
Personally, I think it would have been possible to write one set of rules
to fulfill both needs pretty well, but that would make existing compilers
non-conforming. Better, I think, to recognize one set of rules which is
consistent with what compilers presently do, and another which would allow
many useful optimizations while allowing code to do nearly everything that
would be possible via aliasing.
> It is quite possible that you have a good point in here somewhere. I
> think it is unlikely that you are right but that the C standards
> committee and the gcc developers and the clang developers are all wrong.
Do you think the Committee intends the Standard to be regarded as a full
and complete description of everything something must do to be a quality
C implementation that is suitable for any particular purpose?
I think it would be possible to write a practical and complete specification
which would be free from the "Translation limits" loophole if one allows for
the possibilities that:
1. A conforming implementation may, instead of processing a program as
required by the Standard, indicate an inability to do so via
Implementation-Defined means; no implementation would be required to
run any particular program. Quality implementations should generally
run programs successfully whenever practical, but some kinds of
implementations may promise that any program which is not rejected at
build time will succeed at run time, even if this would mean that they
reject programs that would, in fact, have run successfully.
Note that this would allow for implementations that use run-time stack
checking, as well as those which statically verify stack usage. There
would thus be no need for stack overflow to cause UB.
2. An implementation may specify environmental requirements, and may
behave in arbitrary fashion if the environment fails to meet those
requirements. This avoids loopholes about "should a program be
expected to keep running if someone pulls the plug", etc. since a
power failure would generally result in the environment ceasing to
meet its stated requirements [except e.g. in implementations that
specify that the system must trigger a power-fail interrupt and
remain operational for at least 20ms to allow saving context, which
might then be able to specify behavior once power is restored].
If the Standard endeavored to be complete, then it might be possible to
have a useful category of programs whose behavior would be fully defined
by the Standard save for the possibility of failing in Implementation-
Defined means. As it is, however, I see no evidence that the Standard
makes any real effort at completeness.
> But I can't say I am an expert on the concept of "effective types" - it
> simply has not been an issue in anything I have done. That comes from
> three things, I think. First, I don't write nonsense that converts
> pointers back and forth between float pointers and integer pointers like
> this - if I needed to do something similar, I have unions, memcpy, and
> possibly volatile. Secondly, I rarely use allocated memory - all my
> data has declared types, and they are accessed only as those types.
> Thirdly, if I /do/ need to do something funny, such as making my own
> dynamic memory allocation system, I can use implementation-specific
> features in that kind of code to be sure of getting what I want.
I use float and int types because they are typically both 32-bit types.
In some cases code may need to convert such types (e.g. on platforms
which lack floating-point units, or if it is necessary to convert from
a native floating-point format to an externally-imposed format for
purposes of data interchange), but the primary reason for using float
and int is because they're pre-defined types that have the same size.
Real-world uses of aliasing much more often involve the use of types
uint32_t and uint16_t to process collections of bits [e.g. bitmap
screens], or the use of structures that have some members in common.
> (For the record, I am mostly happy with 6.5p7 regarding which objects
> may be aliased. However, I would have preferred that integer types with
> the same size and representation could alias as well. So typically
> "int" and "long" would alias, or "long" and "long long". But the
> current rules here are consistent with the type compatibility rules, and
> these in turn help enforce a consistency in types that is relevant for
> portability.)
I'm glad we're in agreement here. We both agree that the Standard does not
require that a compiler recognize aliasing between types that have the same
representation. I believe the reason it doesn't do so isn't because the
authors intended that compilers should try to optimize based upon the types
not being compatible, but because they thought compilers for systems where
types have matching representations would recognize that such compatibility
was so obviously useful that they would support it whether or not the
Standard required it.
Further, the Standard tends to avoid describing things which should
obviously be defined on some systems but not others. For example, on
C89 the behavior of -1<<1 was defined even on sign-magnitude systems
which might have difficulty defining a consistent sensible behavior. It
would make sense to define such action as power-of-two multiplication on
two's-complement systems but UB on sign-magnitude systems, but that
would involve treating different kinds of systems differently. Since
there is only one sensible behavior on two's-complement systems in the
cases where multiplying wouldn't overflow, the authors of the Standard
saw no reason to mandate it.
> > What would you suggest as a concise and clear retronym for the language that
> > is suitable for systems programming use?
>
> I use "C" for systems programming. I don't use Ritchie's language, or
> K&R C, or any other pre-C language. Until recently I used C99 - now I
> usually use C11. Most of my code is pure "standard" C - or at least,
> /could/ be pure standard C (with gcc extensions for neater, clearer,
> more efficient or easier checked code - but not needed for correctness).
> A fair amount relies on widely portable implementation-specific
> features, such as the existence of uint8_t. A small amount is
> compiler-specific, and of course interaction with hardware is
> target-specific. My code works correctly (to my knowledge) and
> efficiently regardless of compiler settings - including
> "-fstrict-aliasing", "-fno-wrapv", optimisation flags, etc.
Many kinds of embedded programs could be written with those flags, and
even those that don't could use those flags for most compilation units
if they are respected during whole-program optimization. If, however,
the only way a whole-program optimizer can respect the flags for one
unit is to treat all cross-module calls as opaque, it may be cheaper to
process the entire unit with -fno-strict-aliasing, etc. than to use
different flags in different modules.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-12-23 13:32 +0100 |
| Message-ID | <p1licj$l9j$1@dont-email.me> |
| In reply to | #124593 |
On 22/12/17 17:21, supercat@casperkitty.com wrote: > On Friday, December 22, 2017 at 2:57:25 AM UTC-6, David Brown wrote: I am not going to enter more discussions about what you /think/ the C standards authors thought, what you imagine they meant, what you suppose they thought that other people would assume to be obvious. The C standards describe the C language, and C compilers implement that language. It is simply insane to base a standardised language with a great many compilers, and huge number of programmers, and a vast number of programs, on imagined unwritten assumptions. Even if you were right about what you think the standards authors meant, and even if you are right that your ideas would make a better language, it is /still/ far more important that we work by a set of /written/ specifications rather than vague imagined rules. Can we please leave it at that? >> I use "C" for systems programming. I don't use Ritchie's language, or >> K&R C, or any other pre-C language. Until recently I used C99 - now I >> usually use C11. Most of my code is pure "standard" C - or at least, >> /could/ be pure standard C (with gcc extensions for neater, clearer, >> more efficient or easier checked code - but not needed for correctness). >> A fair amount relies on widely portable implementation-specific >> features, such as the existence of uint8_t. A small amount is >> compiler-specific, and of course interaction with hardware is >> target-specific. My code works correctly (to my knowledge) and >> efficiently regardless of compiler settings - including >> "-fstrict-aliasing", "-fno-wrapv", optimisation flags, etc. > > Many kinds of embedded programs could be written with those flags, and > even those that don't could use those flags for most compilation units > if they are respected during whole-program optimization. If, however, > the only way a whole-program optimizer can respect the flags for one > unit is to treat all cross-module calls as opaque, it may be cheaper to > process the entire unit with -fno-strict-aliasing, etc. than to use > different flags in different modules. > You seem to be saying the opposite of what I wrote. I write all sorts of embedded programs. I don't use "-fstrict-aliasing", and I don't use "-fno-wrapv". My code would not be better, safer, clearer, or more efficient if I /did/ use them.
[toc] | [prev] | [next] | [standalone]
| From | Gareth Owen <gwowen@gmail.com> |
|---|---|
| Date | 2017-12-23 19:35 +0000 |
| Message-ID | <874lohdypy.fsf@gmail.com> |
| In reply to | #124617 |
David Brown <david.brown@hesbynett.no> writes: > I am not going to enter more discussions about what you /think/ the C > standards authors thought, what you imagine they meant, what you > suppose they thought that other people would assume to be obvious. Yes you are. It's pretty clear you're no more capable of stopping yourself responding to him, than he is of posting his idiocy.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-12-26 12:08 -0800 |
| Message-ID | <85d8300f-d59f-403f-b7b0-fde7f7daec22@googlegroups.com> |
| In reply to | #124617 |
On Saturday, December 23, 2017 at 6:32:36 AM UTC-6, David Brown wrote: > The C > standards describe the C language, and C compilers implement that > language. It is simply insane to base a standardised language with a > great many compilers, and huge number of programmers, and a vast number > of programs, on imagined unwritten assumptions. Even if you were right > about what you think the standards authors meant, and even if you are > right that your ideas would make a better language, it is /still/ far > more important that we work by a set of /written/ specifications rather > than vague imagined rules. The standards describe a language which they call C, but which fails to provide all of the features in the languge which Dennis Ritchie invented, and which had been provided by most programs that called themselves C compilers prior\ to the Standards' publication. Perhaps the Standard should refer to its language as High-Level-Only-C to avoid confusion with Ritchie's language, or the language formed by replacing UB with Ritchie's-Language semantics in all cases where the latter would define a behavior that the former would not? I agree the situation is deplorable, but the solution would be for the Standard to officially recognize optional features. To be sure, that's probably politically impossible since such recognition would imply that quality compilers should be able to support such features without having to completely disable optimization.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-12-26 12:36 -0800 |
| Message-ID | <lnfu7xfcpq.fsf@kst-u.example.com> |
| In reply to | #124714 |
supercat@casperkitty.com writes:
> On Saturday, December 23, 2017 at 6:32:36 AM UTC-6, David Brown wrote:
>> standards describe the C language, and C compilers implement that
>> language. It is simply insane to base a standardised language with a
>> great many compilers, and huge number of programmers, and a vast number
>> of programs, on imagined unwritten assumptions. Even if you were right
>> about what you think the standards authors meant, and even if you are
>> right that your ideas would make a better language, it is /still/ far
>> more important that we work by a set of /written/ specifications rather
>> than vague imagined rules.
>
> The standards describe a language which they call C, but which fails to
> provide all of the features in the languge which Dennis Ritchie invented,
> and which had been provided by most programs that called themselves C
> compilers prior\ to the Standards' publication.
>
> Perhaps the Standard should refer to its language as High-Level-Only-C to
> avoid confusion with Ritchie's language, or the language formed by replacing
> UB with Ritchie's-Language semantics in all cases where the latter would
> define a behavior that the former would not?
The language described by the standards has been what we call C for the
past 28 (soon 29) years.
The pre-ANSI languge described by K&R1 already has a name: K&R C. (That
language lack prototypes, among other useful features.)
The language you want C to be doesn't exist. Feel free to define it and
give it any non-confusing name you like.
> I agree the situation is deplorable, but the solution would be for the
> Standard to officially recognize optional features. To be sure, that's
> probably politically impossible since such recognition would imply that
> quality compilers should be able to support such features without having
> to completely disable optimization.
I'll ask you yet one more time to keep track of the "optional features"
that you want to add to the language, and estimate how much bigger the C
standard (or the description of your own C-like language) would have to
be to accomodate them.
--
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 | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-12-27 10:38 +0100 |
| Message-ID | <p1vpnf$2vb$1@dont-email.me> |
| In reply to | #124714 |
On 26/12/17 21:08, supercat@casperkitty.com wrote: > On Saturday, December 23, 2017 at 6:32:36 AM UTC-6, David Brown wrote: >> The C >> standards describe the C language, and C compilers implement that >> language. It is simply insane to base a standardised language with a >> great many compilers, and huge number of programmers, and a vast number >> of programs, on imagined unwritten assumptions. Even if you were right >> about what you think the standards authors meant, and even if you are >> right that your ideas would make a better language, it is /still/ far >> more important that we work by a set of /written/ specifications rather >> than vague imagined rules. > > The standards describe a language which they call C, but which fails to > provide all of the features in the languge which Dennis Ritchie invented, > and which had been provided by most programs that called themselves C > compilers prior\ to the Standards' publication. The language that almost everyone has called "C" for many decades is not identical to the original language that Ritchie developed. (You don't "invent" a language.) That is a /good/ thing - the language we got with the ISO standards is a much better language in many ways. There may be a few minor cases in which there were advantages in that old language - but we are talking about a couple of small steps backwards for many large leaps forward. And pretty much all of these backwards steps, such as they are, can be negated by modern tools if the programmer so desires. (gcc -fwrapv -fno-strict-aliasing is vastly more portable than any compilers in the days of K&R C.) > > Perhaps the Standard should refer to its language as High-Level-Only-C to > avoid confusion with Ritchie's language, or the language formed by replacing > UB with Ritchie's-Language semantics in all cases where the latter would > define a behavior that the former would not? Or perhaps you could join the rest of the C programming world and learn C - as it is today and has been for decades? And like others, you can refer to the old, outdated and mostly irrelevant language as "K&R C" or "pre-ANSI C", to help you keep track. Of course, "K&R C" was never the language you like to think it was. > > I agree the situation is deplorable, Who are you agreeing with here? Who else thinks "the situation is deplorable" - what situation, and what aspects of it are deplorable? Certainly you are not agreeing with me about the current state of the C language or C compilers - I am quite happy with them. Neither the language nor compilers are perfect, but C does a good enough job for what I need and what many other people need, and compilers seem to be getting better all the time (with some regressions, but overall steady improvements). > but the solution would be for the > Standard to officially recognize optional features. To be sure, that's > probably politically impossible since such recognition would imply that > quality compilers should be able to support such features without having > to completely disable optimization. > I think it works fine with the standard as it is, for the most part - optional features are not really very helpful. (I think it is absurd that some aspects of C99 were made optional, or "conditional", in C11.) Compiler implementations are, of course, free to provide extended features - including support for modes equivalent to "-fwrapv" or "-fno-strict-aliasing". The C standards don't have to specify them, as such things are clearly going to be implementation dependant. At most, they could be mentioned in Annex J.5 "Common extensions".
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-12-27 08:14 -0800 |
| Message-ID | <84508e06-5da0-42f0-bbf3-925bcb1d06f2@googlegroups.com> |
| In reply to | #124731 |
On Wednesday, December 27, 2017 at 3:39:09 AM UTC-6, David Brown wrote:
> > The standards describe a language which they call C, but which fails to
> > provide all of the features in the languge which Dennis Ritchie invented,
> > and which had been provided by most programs that called themselves C
> > compilers prior\ to the Standards' publication.
>
> The language that almost everyone has called "C" for many decades is not
> identical to the original language that Ritchie developed. (You don't
> "invent" a language.) That is a /good/ thing - the language we got with
> the ISO standards is a much better language in many ways. There may be
> a few minor cases in which there were advantages in that old language -
> but we are talking about a couple of small steps backwards for many
> large leaps forward. And pretty much all of these backwards steps, such
> as they are, can be negated by modern tools if the programmer so
> desires. (gcc -fwrapv -fno-strict-aliasing is vastly more portable than
> any compilers in the days of K&R C.)
I would suggest that the term "C", as popularly used, doesn't just refer to
the K&R1 subset, but rather to the union of Ritchie's language and the one
in the Standard.
> > Perhaps the Standard should refer to its language as High-Level-Only-C to
> > avoid confusion with Ritchie's language, or the language formed by replacing
> > UB with Ritchie's-Language semantics in all cases where the latter would
> > define a behavior that the former would not?
>
> Or perhaps you could join the rest of the C programming world and learn
> C - as it is today and has been for decades? And like others, you can
> refer to the old, outdated and mostly irrelevant language as "K&R C" or
> "pre-ANSI C", to help you keep track. Of course, "K&R C" was never the
> language you like to think it was.
Can you offer *any* source text which is free of constraint violations,
which the Standard would require all conforming implementations to process
in any particular fashion? Can you describe any non-trivial action which
can be performed by a strictly-conforming program on a freestanding
implementation if one presumes that translation limits won't pose a problem?
> > I agree the situation is deplorable,
>
> Who are you agreeing with here? Who else thinks "the situation is
> deplorable" - what situation, and what aspects of it are deplorable?
What is deplorable is that the Standard makes no effort to specify behaviors
or guarantees that could "only" be supported by 99% of target platforms.
Consider, for example, the simple proposition: integer operations other
than division and remainder must yield some kind of value (not necessarily
deterministic) and/or indicate an overflow in some *implementation-defined*
fashion, but must have no other side-effects. There have been a few
platforms where it would have been expensive to guarantee that. How many
such platforms have ever had a C99 (much less C11) compiler?
I have no trouble believing that there were some platforms where the cost
of extending such a guarantee to all integer arithmetic would have been
significant--perhaps adding 10% to programs' overall run time. The
guarantee would cost orders of magnitude less on any remotely modern
platform, however. I would suggest that the value of such a guarantee is
somewhere between what it cost on platforms where it was expensive, and
what it costs on modern platform. Consequently, the logical situation would
be to allow code that only needs to run on modern platforms to exploit that
guarantee, while requiring code that would have to run efficiently on even
obscure platforms be written to work around its absence.
> > but the solution would be for the
> > Standard to officially recognize optional features. To be sure, that's
> > probably politically impossible since such recognition would imply that
> > quality compilers should be able to support such features without having
> > to completely disable optimization.
>
> I think it works fine with the standard as it is, for the most part -
> optional features are not really very helpful. (I think it is absurd
> that some aspects of C99 were made optional, or "conditional", in C11.)
Any language must do one of the following:
1. Limit the range of targets that can implement it.
2. Limit the range of things an application can do to a fraction of those
the target could support.
3. Both 1 and 2.
4. Define features that will be available on some targets but not others.
I'd say #4 is by far the best choice. You seem to differ.
> Compiler implementations are, of course, free to provide extended
> features - including support for modes equivalent to "-fwrapv" or
> "-fno-strict-aliasing". The C standards don't have to specify them, as
> such things are clearly going to be implementation dependant. At most,
> they could be mentioned in Annex J.5 "Common extensions".
The "extensions" annex didn't list things like wrapping integer semantics,
even though the Rationale makes explicit mention of them as one of the
reasons short unsigned types promote as signed. Their mention in the
rationale implies they were more common than some things listed in that
annex, and the only reason I can see that they weren't listed as extensions
is that their presence was treated as part of the language when targeting
common hardware.
BTW, most of the additional behaviors I've defined could be summed up rather
simply by a rule which is probably what the authors of the rather vague
annex L intended.
An implementation which defines __STDC_SUPERCAT_CONFORMING must satisfy
the following requirements:
1. It must specify a list of requirements for the execution platform.
2. It must specify all means by which it might indicate that it would be
unable to continue processing the program in a fashion consistent
with the Standard (and this annex).
3. Even when the Standard would otherwise impose no requirements, the
implementation must behave in a fashion consistent with *independently*
processing each statement and sub-expression sequentially, with *ONLY*
the following exceptions:
a. If the execution platform fails to behave as specified, or fails
to supply usable storage for the implementation's use when required
to do so, the implementation may do anything.
b. If storage which has been acquired by the implementation and does
not hold live objects is disturbed, the implementation may do
anything.
c. Certain constructs may waive sequencing or other guarantees.
For example, operations done via "restrict"-qualified pointer,
or pointers derived from it, may be considered unsequenced with
regard to operations on objects not accessed via such pointers.
In addition, if the platform specification indicates that storage
may only be externally changed or observed at certain times, a
compiler may apply optimizations based upon that (provided that
such optimizations could not be observed unless the platform were
to violate its contract).
4. Operations which compute a value will either compute some sort of
value, with no side effects, or will fail as defined in #2. Any
use of a casting operator, or reading of an object via pointer,
will behave as though it is reading a bit pattern that is at worst
Unspecified.
5. Any implementation may fail (in Implementation-Defined fashion) when
given any particular program, though quality implementations should
of course seek to process programs successfully whenever practical.
Note that unlike the Standard, this version doesn't need a loophole that
would allow for UB when translation limits are exceeded, power fails, or
anything else. Further, it would make it practical to define a useful
category of programs between Strictly Conforming and Conforming, whose
behavior would be defined on all conforming implementations as either
running usefully or failing in Implementation-Defined fashion, with no
possibility of unconstrained behavior.
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2017-12-27 09:50 -0500 |
| Message-ID | <drO0C.18438$b_.4710@fx23.iad> |
| In reply to | #124714 |
On 12/26/17 3:08 PM, supercat@casperkitty.com wrote: > On Saturday, December 23, 2017 at 6:32:36 AM UTC-6, David Brown wrote: >> The C >> standards describe the C language, and C compilers implement that >> language. It is simply insane to base a standardised language with a >> great many compilers, and huge number of programmers, and a vast number >> of programs, on imagined unwritten assumptions. Even if you were right >> about what you think the standards authors meant, and even if you are >> right that your ideas would make a better language, it is /still/ far >> more important that we work by a set of /written/ specifications rather >> than vague imagined rules. > > The standards describe a language which they call C, but which fails to > provide all of the features in the languge which Dennis Ritchie invented, > and which had been provided by most programs that called themselves C > compilers prior\ to the Standards' publication. > > Perhaps the Standard should refer to its language as High-Level-Only-C to > avoid confusion with Ritchie's language, or the language formed by replacing > UB with Ritchie's-Language semantics in all cases where the latter would > define a behavior that the former would not? > > I agree the situation is deplorable, but the solution would be for the > Standard to officially recognize optional features. To be sure, that's > probably politically impossible since such recognition would imply that > quality compilers should be able to support such features without having > to completely disable optimization. > The C Standard defines a language which provides less promises than you like, because it was decided that it would support a very wide range of platforms beyond what you want to use. There is nothing in the standard that would prevent a given implementation from providing what you like, and in fact, most of what you have asked for is available in popular implementations when invoked with the proper options (you just think they should be the defaults). The Standards committee has made some features optional, and some of these provide fundamentally useful optional features that aren't that hard to define for those systems that it works for (like the exact width types), and others haven't been as useful. The Committee seems to have decided that too many optional features just makes things harder to understand, and are leaving it to other standards or the implementations to define improved behavior for restricted environments (POSIX is one great example for this). Most of your desired optional features sound idea for such an auxiliary standard. Perhaps if you spent some time pulling together all the things you would like and document the various options possible, you could be an agent to help bring something like that to reality. The fact that I haven't heard of such a project currently happening, makes me think that most people think the current Standards and Implementations provide enough guarantees.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-12-20 12:12 -0800 |
| Message-ID | <lnr2rpi2f7.fsf@kst-u.example.com> |
| In reply to | #124531 |
supercat@casperkitty.com writes:
> On Wednesday, December 20, 2017 at 11:26:04 AM UTC-6, David Brown wrote:
[...]
>> gcc's behaviour with "-fstrict-aliasing" is to apply the rules given in
>> the C standards - and to assume that the programmer understands those
>> rules and writes their code appropriately. Calling it "gcc's
>> interpretation" suggests that gcc is picking a non-standard way to look
>> at aliasing and type punning - it is not.
>
> It also assumes that a programmer would rather use an implementation that
> can only support constructs mandated by the Standard, rather than one which
> isn't so limited.
You've said essentially the same thing while rephrasing it to sound negative.
[...]
--
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]
Page 11 of 16 — ← Prev page 1 … 9 10 [11] 12 13 … 16 Next page →
Back to top | Article view | comp.lang.c
csiph-web