Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #171992 > unrolled thread
| Started by | Paul Edwards <mutazilah@gmail.com> |
|---|---|
| First post | 2023-08-10 04:29 -0700 |
| Last post | 2023-09-13 09:40 -0700 |
| Articles | 20 on this page of 359 — 21 participants |
Back to article view | Back to comp.lang.c
bart again (UCX64) Paul Edwards <mutazilah@gmail.com> - 2023-08-10 04:29 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-08-10 12:57 +0100
Re: bart again (UCX64) Paul Edwards <mutazilah@gmail.com> - 2023-08-10 05:07 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-08-10 13:14 +0100
Re: bart again (UCX64) Paul Edwards <mutazilah@gmail.com> - 2023-08-10 06:53 -0700
Re: bart again (UCX64) cross@spitfire.i.gajendra.net (Dan Cross) - 2023-08-16 11:52 +0000
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-08-16 02:31 +0100
Re: bart again (UCX64) Paul Edwards <mutazilah@gmail.com> - 2023-08-28 03:30 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-08-28 11:43 +0100
Re: bart again (UCX64) Paul Edwards <mutazilah@gmail.com> - 2023-08-28 03:47 -0700
Re: bart again (UCX64) "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2023-09-04 18:43 -0700
Re: bart again (UCX64) Paul Edwards <mutazilah@gmail.com> - 2023-08-10 04:59 -0700
Re: bart again (UCX64) Anton Shepelev <anton.txt@g{oogle}mail.com> - 2023-08-28 17:45 +0300
Re: bart again (UCX64) Paul Edwards <mutazilah@gmail.com> - 2023-08-28 19:19 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-08-29 22:01 +0100
Re: bart again (UCX64) Paul Edwards <mutazilah@gmail.com> - 2023-08-29 20:00 -0700
Re: bart again (UCX64) Paul Edwards <mutazilah@gmail.com> - 2023-08-30 00:25 -0700
Re: bart again (UCX64) Paul Edwards <mutazilah@gmail.com> - 2023-08-30 01:35 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-08-30 11:38 +0100
Re: bart again (UCX64) Paul Edwards <mutazilah@gmail.com> - 2023-08-30 07:06 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-08-30 15:53 +0100
Re: bart again (UCX64) Paul Edwards <mutazilah@gmail.com> - 2023-08-30 12:46 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-08-30 22:59 +0100
Re: bart again (UCX64) Paul Edwards <mutazilah@gmail.com> - 2023-08-30 15:54 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-08-31 00:17 +0100
Re: bart again (UCX64) Paul Edwards <mutazilah@gmail.com> - 2023-08-30 16:30 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-08-31 11:58 +0100
Re: bart again (UCX64) Paul Edwards <mutazilah@gmail.com> - 2023-08-31 05:32 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-08-31 14:45 +0100
Re: bart again (UCX64) Paul Edwards <mutazilah@gmail.com> - 2023-08-31 07:43 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-08-31 15:56 +0100
Re: bart again (UCX64) Paul Edwards <mutazilah@gmail.com> - 2023-08-31 08:38 -0700
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-08-31 12:56 -0700
Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-08-31 22:09 +0000
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-01 10:12 +0200
Re: bart again (UCX64) Paul Edwards <mutazilah@gmail.com> - 2023-08-31 23:53 -0700
Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-08-31 14:39 +0000
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-08-31 20:56 +0100
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-08-31 14:36 +0200
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-08-31 15:30 +0100
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-08-31 16:17 +0100
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-08-31 19:36 +0200
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-08-31 20:26 +0100
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-08-31 13:17 -0700
Verbosity in command output (Was: bart again (UCX64)) gazelle@shell.xmission.com (Kenny McCormack) - 2023-08-31 21:43 +0000
Re: Verbosity in command output (Was: bart again (UCX64)) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-08-31 23:31 +0000
Re: Verbosity in command output (Was: bart again (UCX64)) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-08-31 21:36 -0700
Re: Verbosity in command output (Was: bart again (UCX64)) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-01 17:22 +0000
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-08-31 23:07 +0100
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-08-31 15:32 -0700
Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-08-31 22:05 +0000
Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-08-31 22:07 +0000
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-08-31 23:18 +0100
Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-08-31 23:03 +0000
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-08-31 16:46 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-01 01:44 +0100
Re: bart again (UCX64) Paul Edwards <mutazilah@gmail.com> - 2023-08-31 18:09 -0700
Re: bart again (UCX64) "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2023-08-31 18:11 -0700
Re: bart again (UCX64) Paul Edwards <mutazilah@gmail.com> - 2023-08-31 18:14 -0700
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-01 01:38 +0000
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-01 02:40 +0100
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-01 01:29 +0000
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-08-31 20:28 -0700
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-01 11:10 +0200
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-01 12:01 +0100
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-01 13:20 +0200
Re: bart again (UCX64) Richard Harnden <richard.nospam@gmail.com> - 2023-09-01 13:08 +0100
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-01 13:39 +0100
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-01 15:29 +0200
Re: bart again (UCX64) Richard Harnden <richard.nospam@gmail.com> - 2023-09-01 14:32 +0100
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-01 18:14 +0200
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-01 19:01 +0100
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-01 18:53 +0000
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-01 14:53 +0100
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-01 15:57 +0100
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-01 19:07 +0100
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-01 19:27 +0100
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-01 18:55 +0000
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-01 21:27 +0100
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-01 20:46 +0000
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-01 22:29 +0100
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-01 22:19 +0000
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-03 13:56 +0100
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-03 15:31 +0100
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-03 16:05 +0100
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-04 03:17 +0100
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-04 10:34 +0100
Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-04 03:07 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-04 11:43 +0100
Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-04 04:21 -0700
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-04 17:16 +0100
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-04 18:33 +0100
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-05 01:33 +0100
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-04 15:27 +0200
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-04 17:18 +0100
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-04 16:26 +0000
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-04 19:33 +0100
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-04 19:17 +0000
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-04 20:48 +0100
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-04 21:25 +0100
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-04 21:56 +0000
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-05 01:34 +0100
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-04 21:06 +0100
Re: bart again (UCX64) "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2023-09-04 13:09 -0700
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-04 16:04 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-05 00:52 +0100
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-04 17:16 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-05 15:33 +0100
Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-09-05 14:55 +0000
Re: bart again (UCX64) Bobby Moore <bobbymoore018@gmail.com> - 2023-09-05 08:30 -0700
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-05 17:31 +0200
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-05 18:06 +0100
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-05 17:54 +0000
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-05 20:10 +0200
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-05 20:57 +0100
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-05 22:37 +0200
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-05 22:05 +0100
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-05 15:10 -0700
Re: bart again (UCX64) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-09-06 22:32 -0700
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-07 06:49 +0000
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-06 16:08 +0200
Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-06 07:53 -0700
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-06 17:35 +0200
Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-06 09:37 -0700
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-06 20:49 +0200
Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-09-06 19:51 +0000
Re: bart again (UCX64) "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2023-09-06 12:52 -0700
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-07 00:36 +0100
Re: bart again (UCX64) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-09-06 17:06 -0700
Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-06 18:47 -0700
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-07 11:11 +0200
Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-07 04:04 -0700
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-07 13:24 +0200
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-06 18:13 +0100
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-06 21:17 +0200
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-06 22:24 +0100
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-07 11:37 +0200
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-07 11:53 +0100
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-07 13:33 +0200
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-07 14:36 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-07 22:59 +0100
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-07 16:58 -0700
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-08 00:35 +0000
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-05 20:41 +0000
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-05 20:47 +0000
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-05 14:07 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-05 22:22 +0100
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-05 15:26 -0700
Re: bart again (UCX64) Richard Damon <Richard@Damon-Family.org> - 2023-09-05 18:26 -0700
Re: bart again (UCX64) James Kuyper <jameskuyper@alumni.caltech.edu> - 2023-09-07 23:15 -0400
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-05 13:48 -0700
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-05 21:36 +0000
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-05 13:24 +0200
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-04 15:46 -0700
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-02 17:44 +0200
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-02 01:14 +0100
Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-01 18:13 -0700
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-02 01:43 +0000
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-02 17:51 +0200
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-02 17:58 +0200
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-02 23:28 +0100
Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-02 20:09 -0700
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-03 07:15 +0000
Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-03 03:03 -0700
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-03 18:53 +0000
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-03 16:24 +0100
Re: bart again (UCX64) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-09-03 12:22 -0700
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-04 02:01 +0100
Re: bart again (UCX64) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-09-05 21:40 -0700
[OT] Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-06 17:06 +0100
Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-03 18:02 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-02 10:39 +0100
Re: bart again (UCX64) Richard Damon <Richard@Damon-Family.org> - 2023-09-02 07:33 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-02 16:26 +0100
Re: bart again (UCX64) Richard Damon <Richard@Damon-Family.org> - 2023-09-02 09:03 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-02 19:22 +0100
Re: bart again (UCX64) vallor <vallor@cultnix.org> - 2023-09-05 01:38 +0000
Re: bart again (UCX64) Richard Damon <Richard@Damon-Family.org> - 2023-09-04 20:05 -0700
Re: bart again (UCX64) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-09-06 16:45 -0700
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-05 06:49 +0000
Re: bart again (UCX64) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-09-05 05:30 -0700
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-05 17:16 +0000
Re: bart again (UCX64) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-09-06 08:47 -0700
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-06 19:57 +0100
Re: bart again (UCX64) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-09-06 19:01 -0700
Re: bart again (UCX64) James Kuyper <jameskuyper@alumni.caltech.edu> - 2023-09-09 01:14 -0400
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-09 05:22 +0000
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-05 12:51 +0100
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-02 12:58 -0700
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-02 16:29 +0000
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-02 20:00 +0100
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-03 00:08 +0100
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-03 01:36 +0100
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-03 02:41 +0100
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-02 17:49 +0200
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-01 18:32 +0000
Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-09-01 18:59 +0000
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-02 18:02 +0200
Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-09-03 15:54 +0000
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-03 19:50 +0200
Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-09-03 21:25 +0000
Re: bart again (UCX64) "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2023-09-03 16:44 -0700
Re: bart again (UCX64) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-09-03 11:47 -0700
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-01 18:16 +0000
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-01 17:48 +0000
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-01 19:12 +0100
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-01 18:49 +0000
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-01 21:33 +0100
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-01 21:09 +0000
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-01 22:41 +0100
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-01 22:34 +0000
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-01 15:51 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-02 14:06 +0100
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-02 17:27 +0000
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-01 16:02 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-02 01:50 +0100
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-02 01:12 +0000
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-01 19:13 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-02 11:57 +0100
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-02 18:19 +0200
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-02 19:53 +0100
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-03 06:32 +0000
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-03 16:02 +0200
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-03 18:11 +0100
Re: bart again (UCX64) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-09-03 11:31 -0700
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-03 20:07 +0100
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-03 22:08 +0100
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-04 03:16 +0100
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-04 10:54 +0200
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-04 11:06 +0100
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-04 14:54 +0100
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-04 22:02 +0100
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-05 01:31 +0100
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-05 02:24 +0100
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-06 04:29 +0100
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-05 21:06 -0700
Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-06 01:03 -0700
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-06 20:58 +0100
Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-06 19:21 -0700
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-07 20:18 +0100
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-06 13:07 +0100
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-06 22:41 +0100
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-06 15:56 -0700
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-07 00:53 +0100
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-06 18:47 -0700
Re: bart again (UCX64) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-09-06 17:25 -0700
Re: bart again (UCX64) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-09-12 10:32 -0700
Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-04 18:30 -0700
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-06 03:04 +0100
Re: bart again (UCX64) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-09-06 21:48 -0700
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-07 06:10 +0000
Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-07 02:06 -0700
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-07 15:52 +0000
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-07 14:18 -0700
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-07 15:28 +0100
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-07 16:54 +0200
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-07 17:02 +0100
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-07 16:12 +0000
Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-09-07 16:17 +0000
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-07 17:37 +0100
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-07 14:51 -0700
Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-08 00:46 -0700
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-08 11:06 +0200
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-08 10:19 +0200
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-07 15:55 +0100
Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-09-07 15:16 +0000
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-07 17:02 +0100
Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-09-07 16:15 +0000
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-07 17:51 +0100
Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-09-07 17:24 +0000
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-07 21:53 +0100
Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-09-07 21:34 +0000
Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-09-07 17:25 +0000
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-07 21:37 +0100
Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-09-07 21:02 +0000
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-07 16:14 -0700
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-07 16:09 -0700
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-07 17:34 +0100
Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-09-07 17:22 +0000
Re: bart again (UCX64) Richard Damon <Richard@Damon-Family.org> - 2023-09-07 11:44 -0700
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-07 15:16 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-07 23:48 +0100
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-07 17:16 -0700
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-08 11:16 +0200
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-08 10:51 +0100
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-08 13:00 +0200
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-08 13:05 +0100
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-08 16:11 +0200
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-09 00:56 +0000
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-09 00:47 +0000
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-09 18:49 +0200
Re: bart again (UCX64) Richard Damon <Richard@Damon-Family.org> - 2023-09-09 10:27 -0700
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-10 12:06 +0200
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-08 05:03 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-08 13:39 +0100
Re: bart again (UCX64) candycanearter07 <no@thanks.net> - 2023-09-08 07:49 -0500
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-09 01:07 +0000
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-09 18:51 +0200
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-08 16:35 +0200
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-09 01:04 +0000
Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-09-04 14:14 +0000
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-04 16:59 +0200
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-04 15:41 -0700
Re: bart again (UCX64) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-09-04 18:15 -0700
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-04 18:57 -0700
Re: bart again (UCX64) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-09-30 09:23 -0700
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-30 15:55 -0700
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-02 17:10 +0000
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-02 13:13 -0700
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-02 22:50 +0100
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-02 14:54 -0700
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-01 19:02 -0700
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-02 22:42 +0100
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-02 15:08 -0700
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-03 02:00 +0100
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-02 23:18 +0100
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-03 02:28 +0100
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-03 06:58 +0000
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-03 15:52 +0100
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-03 11:02 +0100
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-03 16:25 +0200
Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-03 16:49 +0100
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-03 16:16 +0200
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-02 18:11 +0200
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-02 22:08 +0100
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-03 16:48 +0200
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-02 14:52 -0700
Re: bart again (UCX64) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-09-03 02:23 -0700
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-03 03:47 -0700
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-03 18:44 +0000
Re: bart again (UCX64) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-09-03 18:01 -0700
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-03 16:59 +0200
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-03 17:50 -0700
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-01 10:43 +0200
Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-01 02:17 -0700
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-01 13:26 +0200
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-01 11:35 +0100
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-01 13:39 +0200
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-01 14:09 +0100
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-01 15:33 +0200
Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-01 05:14 -0700
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-01 17:41 +0000
Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-09-01 18:21 +0000
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-01 14:31 -0700
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-01 22:39 +0000
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-02 07:07 +0000
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-08-31 19:17 +0000
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-08-31 19:28 +0000
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-08-31 21:03 +0100
Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-01 11:23 +0200
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-08-31 20:50 +0100
Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-08-31 23:12 +0000
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-01 02:25 +0100
Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-08-31 20:37 -0700
Re: bart again (UCX64) Paul Edwards <mutazilah@gmail.com> - 2023-08-30 07:51 -0700
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-08-30 16:09 +0100
Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-08-30 20:17 +0100
Re: bart again (UCX64) Michael S <already5chosen@yahoo.com> - 2023-08-29 04:46 -0700
Buy Magic Mushrooms online Buy Magic Mushroom Chocolate Bars <taresa67kolyta@gmail.com> - 2023-09-13 09:40 -0700
Page 7 of 18 — ← Prev page 1 … 5 6 [7] 8 9 … 18 Next page →
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2023-09-06 16:08 +0200 |
| Message-ID | <uda158$2hcdt$1@dont-email.me> |
| In reply to | #174047 |
On 05/09/2023 23:05, Bart wrote: > On 05/09/2023 21:37, David Brown wrote: >> On 05/09/2023 21:57, Bart wrote: > >>> 6.8.6.4p1 says: > >>> It doesn't say anything about Non-void functions, so we have to draw >>> inferences: presumably (1) must be 'Only here', and (2) must be 'Not >>> allowed'. So: >>> >>> (Proc) (Func) (My terms) >>> Void func Non-void func >>> >>> return expr; N Y >>> >>> return; Y N >>> >>> A bit clearer, yes? Maybe /I/ should be writing it! I already >>> implement these because they are common sense, but the question was, >>> what should a compiler do about infringements. >>> >>> This paragraph calls them Constraints, as presumably they can't be >>> expressed via syntax. >> >> Yes. (Or at least, the rules are not expressed by the syntax - maybe >> they could have been, but it seemed easier to express them as >> constraints.) >> >>> >>> I guess some other sections explains how those are handled. >> >> It's all quite clear - you got it. (There are certainly some parts of >> the standard that are harder to figure out.) >> >> Note that it does not say anywhere that you /must/ have a return >> statement - with or without an expression. It merely says what kind >> of return statements are allowed. So there is no requirement anywhere >> here for a function to have a "return <expression>" statement even if >> the function is non-void. > > > So my summary was wrong. It is more like this: > > (Proc) (Func) (My terms) > Void func Non-void func > > return expr; N Optional > > return; Optional N > > Optional for a procedure is right, since running into the end of the > function is OK because the compiler will ensure there is a 'return' there. I took the "Y" in your first summary to mean "yes, this is allowed". If you prefer to write that as "optional", that's fine. > > So my main disagreement is with the Optional return of non-void > functions (which I've now given up on), and how seriously infringements > of those 'N' cases are reported. Just to be clear here - and I /really/ hope you will answer this one simply and unambiguously - do you understand that the C standards make the return statement optional? Do you understand that this is what the C standards say - it is not something that C compilers choose, or that C programmers in this group have decided? I'd have been happy to see C defined in a way that makes it undefined behaviour if a non-void function reaches the terminating close brace. I would not have been happy to see it defined to require a "return expr" statement in non-void functions, because I think these things should be about the behaviour of functions, not their syntax. But I personally don't see the current standard rules here as a big issue, because they rule out misuse (you are not allowed to attempt to use the value of falling off the end of a non-void function), and they do not force programmers to write code that is never executed. It is all very simple and natural in terms of how functions and calls are typically implemented. This all follows a common pattern for C - the standards define what useful and meaningful code does, but do not attempt to enforce good programming practice, since that varies hugely for different use-cases. It is up to tools to aid users in their development, not the C language. Tool vendors know their audience and their needs - the needs of someone coding a little game on Windows, those of someone making a rocket engine controller, and those of someone maintaining 40 year old code are totally different. And the preferences for different programmers vary wildly. Since most tools are targeted at many different people and coding styles, they support options to let users decide what they need. Other tools are more specialised - specific checkers for the Linux kernel, MISRA rule checkers for the automotive industry, and so on. (C tools are not restricted to compilers - from its inception, it was expected that linters and other checkers would be independent from compilers.) Sometimes there are things that perhaps 95% of users agree is likely to be bad coding. A tool might flag the potential error by default - but it might not, for many different reasons. Even if 99.9% of users agree, however, it is not the compiler's job to overrule the definition of the language in the standards - it has to allow the code. It can give warnings, it can require flags or options, but it has to allow it. > > Because a compiler could also have have ensured that running into the > end of a non-void function sets up a default return value such as > all-zeros. A compiler certainly /could/ do that. I'd question the usefulness of it, but maybe some people would like it. My own preference, as you know, is for the compiler to detect and flag potential problems such as running off the end of a non-void function as a hard error - just like your preference. The only differences are that I know that I am asking for a subset of C, I am asking for a restriction that not everyone wants, I understand that C compilers should not have this kind of restriction as a default, and I know how to ask my tools to enforce the restrictions I want. > >> Running off the end of a non-void function is only a problem if the >> the caller tries to use the value. > > Which in general you can't determine, and is incredibly sloppy anyway. > Most run-time errors can't be determined in advance - certainly not by simple static rules. (Again, I prefer warnings or even errors for this situation - but that is /my/ preference, and is not a requirement of the C standards, and not what all C programmers want in all circumstances.) > >> Otherwise it is fine. > > Assuming it doesn't affect the mechanics of how function calls work in > the target. A stack-based target /must/ push some return value, > otherwise it'll interpret some wrong value as the return address. > I could only imagine this happing in a C implementation on a machine that has separate return and data stacks - I don't know any such systems, but they could hypothetically exist. The solution there would be to push a fake return value (perhaps all zeros, perhaps random). In more common single-stack systems, return values are either in registers, or in stack space allocated by the caller, not the callee. >>> You sound like a Jehovah's Witness. >> >> The difference is, the C standard is real. > > They're both written by humans. I don't really want to get into religious discussions. But you could read through the C standards in a day and have a pretty good idea of most of it, and be familiar enough to find the references you need when you want them. It would probably take a couple of years to reach the same level of familiarity with the Bible - the comparison between the two documents is clearly absurd. > >> Once you know what it says here, so you understand how the language is >> defined, /then/ it makes sense to ask /why/ it is defined that way. >> (And I quite appreciate that you want to know why - I too like to know >> the reasons behind decisions.) >> >>> >>>> And stick to one thing at a time. Two thoughts on the same day >>>> appear to be beyond you, and we don't want you to get confused again. >>> >>> Yeah, well I'm busy actually implementing C at the moment. > >> Well, I'm glad you have now found a copy of one of the C standards >> (which one?), and are starting to show an interest in finding out how >> the language is defined. > > You really think I haven't looked at it before? I don't think you have made noticeable effort to read it or understand it, no. > >> It will make it much easier to write a C implementation. > > 99% of the work is nothing to do with the standard. It's a slog. A lot > of it caused by so much diversity in all the C code out there, /because/ > people have too much freedom to write what they like. > The standard is what defines the language. How could it not be important?
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.arthur.mclean@gmail.com> |
|---|---|
| Date | 2023-09-06 07:53 -0700 |
| Message-ID | <218901fb-053e-473d-b566-2840b2652117n@googlegroups.com> |
| In reply to | #174145 |
On Wednesday, 6 September 2023 at 15:08:56 UTC+1, David Brown wrote: > Bart > I'd have been happy to see C defined in a way that makes it undefined > behaviour if a non-void function reaches the terminating close brace. I > would not have been happy to see it defined to require a "return expr" > statement in non-void functions, because I think these things should be > about the behaviour of functions, not their syntax. But I personally > don't see the current standard rules here as a big issue, because they > rule out misuse (you are not allowed to attempt to use the value of > falling off the end of a non-void function), and they do not force > programmers to write code that is never executed. It is all very simple > and natural in terms of how functions and calls are typically implemented. > The way some other languages do it is to have a special variable which is the return value. (Often it has the same name as the function). That variable is the returned whne the function exits. So it's not possible to write a function that returns nothing on some control paths. > > > Tool vendors know their audience and their needs - the needs of > someone coding a little game on Windows, those of someone making a > rocket engine controller, and those of someone maintaining 40 year old > code are totally different. > Yes, but no-one wants "functions" which sometimes return a value and sometimes don't. In a little game no real harm can be done, whilst in a rocket engine contoller an expensive rocket might blow up, but it's the same bug. > > > Assuming it doesn't affect the mechanics of how function calls work in > > the target. A stack-based target /must/ push some return value, > > otherwise it'll interpret some wrong value as the return address. > > > I could only imagine this happing in a C implementation on a machine > that has separate return and data stacks - I don't know any such > systems, but they could hypothetically exist. The solution there would > be to push a fake return value (perhaps all zeros, perhaps random). > > In more common single-stack systems, return values are either in > registers, or in stack space allocated by the caller, not the callee. > There are two ways of doing it on a single stack-based system. The first is to push the arguments in caller, then push a dummy value for the return value, which is later filled in by the callee. The other way is to push just the arguments, and make the callee push the return value. It's just a minor implementation decision. But if you choose option two, then callee has to push something even if control falls off the bottom of the fuction with no return, because otherwise when caller pops the stack, he will corrupt it. > > >>> You sound like a Jehovah's Witness. > >> > >> The difference is, the C standard is real. > > > > They're both written by humans. > I don't really want to get into religious discussions. But you could > read through the C standards in a day and have a pretty good idea of > most of it, and be familiar enough to find the references you need when > you want them. It would probably take a couple of years to reach the > same level of familiarity with the Bible - the comparison between the > two documents is clearly absurd. > The C standard really is inerrant, because we've agreed that "C" means whatever the standard says it means. Even if it is stupid, or pig-ignorant. > > > 99% of the work is nothing to do with the standard. It's a slog. A lot > > of it caused by so much diversity in all the C code out there, /because/ > > people have too much freedom to write what they like. > > > The standard is what defines the language. How could it not be important? > You can have good enough conformance. Some conforming programs written in deliberately odd ways might compile incorrectly, but that would be a minor defect.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2023-09-06 17:35 +0200 |
| Message-ID | <uda68g$2i84h$1@dont-email.me> |
| In reply to | #174153 |
On 06/09/2023 16:53, Malcolm McLean wrote: > On Wednesday, 6 September 2023 at 15:08:56 UTC+1, David Brown wrote: >> Bart > >> I'd have been happy to see C defined in a way that makes it undefined >> behaviour if a non-void function reaches the terminating close brace. I >> would not have been happy to see it defined to require a "return expr" >> statement in non-void functions, because I think these things should be >> about the behaviour of functions, not their syntax. But I personally >> don't see the current standard rules here as a big issue, because they >> rule out misuse (you are not allowed to attempt to use the value of >> falling off the end of a non-void function), and they do not force >> programmers to write code that is never executed. It is all very simple >> and natural in terms of how functions and calls are typically implemented. >> > The way some other languages do it is to have a special variable which is > the return value. (Often it has the same name as the function). That variable > is the returned whne the function exits. So it's not possible to write a function > that returns nothing on some control paths. That's true. But it is still entirely possible to return nonsense. Some languages will choose to initialise the return variable to a default dummy value, making that a minimum return value. I've never been a fan of that idea - such defaults are often incorrect and invalid for the specification of the function, and I'd rather have compiler warnings about missing return values (just as I'd rather not have local variables be default initialised). No matter how a programming language defines these things, there are no general methods to guarantee that the function returns the correct value (or /a/ correct value, if there are several possibilities) according to its requirements. And if it is not going to return a correct value, why fuss about what it does or does not return - the code is buggy. The best a language and/or tool can do is tell you when you are likely, according to common practices, to have made a mistake. C compilers do that just as well as Pascal compilers do, or other languages that have a special return variable. >> >> >> Tool vendors know their audience and their needs - the needs of >> someone coding a little game on Windows, those of someone making a >> rocket engine controller, and those of someone maintaining 40 year old >> code are totally different. >> > Yes, but no-one wants "functions" which sometimes return a value and sometimes > don't. Really? Do you speak for all programmers here? Ben gave an example earlier of a function that has a non-void return type, but which will never return any value because it never returns. I'll accept that in almost all cases, you either want to be sure that a function returns the correct value, or that you have some way of knowing that you have a good return value. Many modern languages have natural support for that - a Python function might return a value or None, a C++ function might return a std::optional<>, and other languages have ways of indicating success or failure. I think it is rare to find uses for functions where you might get a valid return, or might not, and have no clear way of determining the case. > In a little game no real harm can be done, whilst in a rocket engine > contoller an expensive rocket might blow up, but it's the same bug. People writing rocket engine controllers know how to to use their tools and high quality development processes - such bugs will never occur in their code, regardless of the language used. >> >>> Assuming it doesn't affect the mechanics of how function calls work in >>> the target. A stack-based target /must/ push some return value, >>> otherwise it'll interpret some wrong value as the return address. >>> >> I could only imagine this happing in a C implementation on a machine >> that has separate return and data stacks - I don't know any such >> systems, but they could hypothetically exist. The solution there would >> be to push a fake return value (perhaps all zeros, perhaps random). >> >> In more common single-stack systems, return values are either in >> registers, or in stack space allocated by the caller, not the callee. >> > There are two ways of doing it on a single stack-based system. > The first is to push the arguments in caller, then push a dummy value > for the return value, which is later filled in by the callee. The other way > is to push just the arguments, and make the callee push the return value. In theory, there are many ways these things can be done. In practice, there are very few that make sense on most processors. Your second method here is never used in reality. For general processors, return values are either in registers, or the caller allocates space on the stack before calling. A pointer to this space may be passed as a hidden parameter, or the callee may find it implicitly as a fixed offset from the stack pointer. (If the size is unknown, as might be the case in a dynamically typed language, the actual return value will be a fixed-size pointer or proxy object of some kind.) For some very small CISC microcontrollers, return values can be placed in specific fixed addresses in ram. It makes no sense for a function to push a return value, because then it could no longer use a "return" assembly instruction - you need the return address will be at the top of the stack. It would not be /impossible/ to dig the return address out the stack and do an indirect jump, but doing so would be extra complications, break C ABI's, and undermine the hardware accelerations and optimisations that modern processors have to make "return" instructions as fast as possible. (RISC processors generally have more flexibility for return addresses, but much of the same logic still applies - and it would make C ABI's more complicated.) > > It's just a minor implementation decision. But if you choose option two, > then callee has to push something even if control falls off the bottom > of the fuction with no return, because otherwise when caller pops the > stack, he will corrupt it. That's true, which is a reason why option two is never used. >> >>>>> You sound like a Jehovah's Witness. >>>> >>>> The difference is, the C standard is real. >>> >>> They're both written by humans. >> I don't really want to get into religious discussions. But you could >> read through the C standards in a day and have a pretty good idea of >> most of it, and be familiar enough to find the references you need when >> you want them. It would probably take a couple of years to reach the >> same level of familiarity with the Bible - the comparison between the >> two documents is clearly absurd. >> > The C standard really is inerrant, because we've agreed that "C" means > whatever the standard says it means. Even if it is stupid, or pig-ignorant. Yes, that's how standards work. >> >>> 99% of the work is nothing to do with the standard. It's a slog. A lot >>> of it caused by so much diversity in all the C code out there, /because/ >>> people have too much freedom to write what they like. >>> >> The standard is what defines the language. How could it not be important? >> > You can have good enough conformance. Some conforming programs written > in deliberately odd ways might compile incorrectly, but that would be a minor > defect. > A compiler does not have to be fully conformant to any given C standard, and such compilers can be a lot more useful than standard-pedantic compilers for some uses. Almost all my coding relies on compiler extensions to some extent.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.arthur.mclean@gmail.com> |
|---|---|
| Date | 2023-09-06 09:37 -0700 |
| Message-ID | <9db7b845-cc12-490f-bc68-a402870d4636n@googlegroups.com> |
| In reply to | #174160 |
On Wednesday, 6 September 2023 at 16:35:57 UTC+1, David Brown wrote: > On 06/09/2023 16:53, Malcolm McLean wrote: > > On Wednesday, 6 September 2023 at 15:08:56 UTC+1, David Brown wrote: > >> Bart > > > >> I'd have been happy to see C defined in a way that makes it undefined > >> behaviour if a non-void function reaches the terminating close brace. I > >> would not have been happy to see it defined to require a "return expr" > >> statement in non-void functions, because I think these things should be > >> about the behaviour of functions, not their syntax. But I personally > >> don't see the current standard rules here as a big issue, because they > >> rule out misuse (you are not allowed to attempt to use the value of > >> falling off the end of a non-void function), and they do not force > >> programmers to write code that is never executed. It is all very simple > >> and natural in terms of how functions and calls are typically implemented. > >> > > The way some other languages do it is to have a special variable which is > > the return value. (Often it has the same name as the function). That variable > > is the returned whne the function exits. So it's not possible to write a function > > that returns nothing on some control paths. > That's true. But it is still entirely possible to return nonsense. > Some languages will choose to initialise the return variable to a > default dummy value, making that a minimum return value. I've never > been a fan of that idea - such defaults are often incorrect and invalid > for the specification of the function, and I'd rather have compiler > warnings about missing return values (just as I'd rather not have local > variables be default initialised). > > No matter how a programming language defines these things, there are no > general methods to guarantee that the function returns the correct value > (or /a/ correct value, if there are several possibilities) according to > its requirements. And if it is not going to return a correct value, why > fuss about what it does or does not return - the code is buggy. The > best a language and/or tool can do is tell you when you are likely, > according to common practices, to have made a mistake. C compilers do > that just as well as Pascal compilers do, or other languages that have a > special return variable. > >> > >> > >> Tool vendors know their audience and their needs - the needs of > >> someone coding a little game on Windows, those of someone making a > >> rocket engine controller, and those of someone maintaining 40 year old > >> code are totally different. > >> > > Yes, but no-one wants "functions" which sometimes return a value and sometimes > > don't. > Really? Do you speak for all programmers here? Ben gave an example > earlier of a function that has a non-void return type, but which will > never return any value because it never returns. > > I'll accept that in almost all cases, you either want to be sure that a > function returns the correct value, or that you have some way of knowing > that you have a good return value. Many modern languages have natural > support for that - a Python function might return a value or None, a C++ > function might return a std::optional<>, and other languages have ways > of indicating success or failure. I think it is rare to find uses for > functions where you might get a valid return, or might not, and have no > clear way of determining the case. > > In a little game no real harm can be done, whilst in a rocket engine > > contoller an expensive rocket might blow up, but it's the same bug. > People writing rocket engine controllers know how to to use their tools > and high quality development processes - such bugs will never occur in > their code, regardless of the language used. > >> > >>> Assuming it doesn't affect the mechanics of how function calls work in > >>> the target. A stack-based target /must/ push some return value, > >>> otherwise it'll interpret some wrong value as the return address. > >>> > >> I could only imagine this happing in a C implementation on a machine > >> that has separate return and data stacks - I don't know any such > >> systems, but they could hypothetically exist. The solution there would > >> be to push a fake return value (perhaps all zeros, perhaps random). > >> > >> In more common single-stack systems, return values are either in > >> registers, or in stack space allocated by the caller, not the callee. > >> > > There are two ways of doing it on a single stack-based system. > > The first is to push the arguments in caller, then push a dummy value > > for the return value, which is later filled in by the callee. The other way > > is to push just the arguments, and make the callee push the return value. > In theory, there are many ways these things can be done. In practice, > there are very few that make sense on most processors. Your second > method here is never used in reality. For general processors, return > values are either in registers, or the caller allocates space on the > stack before calling. A pointer to this space may be passed as a hidden > parameter, or the callee may find it implicitly as a fixed offset from > the stack pointer. (If the size is unknown, as might be the case in a > dynamically typed language, the actual return value will be a fixed-size > pointer or proxy object of some kind.) For some very small CISC > microcontrollers, return values can be placed in specific fixed > addresses in ram. > > It makes no sense for a function to push a return value, because then it > could no longer use a "return" assembly instruction - you need the > return address will be at the top of the stack. It would not be > /impossible/ to dig the return address out the stack and do an indirect > jump, but doing so would be extra complications, break C ABI's, and > undermine the hardware accelerations and optimisations that modern > processors have to make "return" instructions as fast as possible. > (RISC processors generally have more flexibility for return addresses, > but much of the same logic still applies - and it would make C ABI's > more complicated.) > RISC processors often have "jump and link" rather than "call". The stack is purely conventional, it doesn't mean anything at the silicon level. "Jump and link" places the current program counter in a designated register, then jumps to an address. So a leaf function can simply "jump to link register" to return. A non-leaf function has to save the link register on the stack and retrieve it. Since caller doesn't know whether a function is leaf or not, in this case the return address would have to be pushed by the callee.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2023-09-06 20:49 +0200 |
| Message-ID | <udahj4$2k0hb$1@dont-email.me> |
| In reply to | #174171 |
On 06/09/2023 18:37, Malcolm McLean wrote: > On Wednesday, 6 September 2023 at 16:35:57 UTC+1, David Brown wrote: >> On 06/09/2023 16:53, Malcolm McLean wrote: >>> On Wednesday, 6 September 2023 at 15:08:56 UTC+1, David Brown wrote: >>>> Bart >>> >>>> I'd have been happy to see C defined in a way that makes it undefined >>>> behaviour if a non-void function reaches the terminating close brace. I >>>> would not have been happy to see it defined to require a "return expr" >>>> statement in non-void functions, because I think these things should be >>>> about the behaviour of functions, not their syntax. But I personally >>>> don't see the current standard rules here as a big issue, because they >>>> rule out misuse (you are not allowed to attempt to use the value of >>>> falling off the end of a non-void function), and they do not force >>>> programmers to write code that is never executed. It is all very simple >>>> and natural in terms of how functions and calls are typically implemented. >>>> >>> The way some other languages do it is to have a special variable which is >>> the return value. (Often it has the same name as the function). That variable >>> is the returned whne the function exits. So it's not possible to write a function >>> that returns nothing on some control paths. >> That's true. But it is still entirely possible to return nonsense. >> Some languages will choose to initialise the return variable to a >> default dummy value, making that a minimum return value. I've never >> been a fan of that idea - such defaults are often incorrect and invalid >> for the specification of the function, and I'd rather have compiler >> warnings about missing return values (just as I'd rather not have local >> variables be default initialised). >> >> No matter how a programming language defines these things, there are no >> general methods to guarantee that the function returns the correct value >> (or /a/ correct value, if there are several possibilities) according to >> its requirements. And if it is not going to return a correct value, why >> fuss about what it does or does not return - the code is buggy. The >> best a language and/or tool can do is tell you when you are likely, >> according to common practices, to have made a mistake. C compilers do >> that just as well as Pascal compilers do, or other languages that have a >> special return variable. >>>> >>>> >>>> Tool vendors know their audience and their needs - the needs of >>>> someone coding a little game on Windows, those of someone making a >>>> rocket engine controller, and those of someone maintaining 40 year old >>>> code are totally different. >>>> >>> Yes, but no-one wants "functions" which sometimes return a value and sometimes >>> don't. >> Really? Do you speak for all programmers here? Ben gave an example >> earlier of a function that has a non-void return type, but which will >> never return any value because it never returns. >> >> I'll accept that in almost all cases, you either want to be sure that a >> function returns the correct value, or that you have some way of knowing >> that you have a good return value. Many modern languages have natural >> support for that - a Python function might return a value or None, a C++ >> function might return a std::optional<>, and other languages have ways >> of indicating success or failure. I think it is rare to find uses for >> functions where you might get a valid return, or might not, and have no >> clear way of determining the case. >>> In a little game no real harm can be done, whilst in a rocket engine >>> contoller an expensive rocket might blow up, but it's the same bug. >> People writing rocket engine controllers know how to to use their tools >> and high quality development processes - such bugs will never occur in >> their code, regardless of the language used. >>>> >>>>> Assuming it doesn't affect the mechanics of how function calls work in >>>>> the target. A stack-based target /must/ push some return value, >>>>> otherwise it'll interpret some wrong value as the return address. >>>>> >>>> I could only imagine this happing in a C implementation on a machine >>>> that has separate return and data stacks - I don't know any such >>>> systems, but they could hypothetically exist. The solution there would >>>> be to push a fake return value (perhaps all zeros, perhaps random). >>>> >>>> In more common single-stack systems, return values are either in >>>> registers, or in stack space allocated by the caller, not the callee. >>>> >>> There are two ways of doing it on a single stack-based system. >>> The first is to push the arguments in caller, then push a dummy value >>> for the return value, which is later filled in by the callee. The other way >>> is to push just the arguments, and make the callee push the return value. >> In theory, there are many ways these things can be done. In practice, >> there are very few that make sense on most processors. Your second >> method here is never used in reality. For general processors, return >> values are either in registers, or the caller allocates space on the >> stack before calling. A pointer to this space may be passed as a hidden >> parameter, or the callee may find it implicitly as a fixed offset from >> the stack pointer. (If the size is unknown, as might be the case in a >> dynamically typed language, the actual return value will be a fixed-size >> pointer or proxy object of some kind.) For some very small CISC >> microcontrollers, return values can be placed in specific fixed >> addresses in ram. >> >> It makes no sense for a function to push a return value, because then it >> could no longer use a "return" assembly instruction - you need the >> return address will be at the top of the stack. It would not be >> /impossible/ to dig the return address out the stack and do an indirect >> jump, but doing so would be extra complications, break C ABI's, and >> undermine the hardware accelerations and optimisations that modern >> processors have to make "return" instructions as fast as possible. >> (RISC processors generally have more flexibility for return addresses, >> but much of the same logic still applies - and it would make C ABI's >> more complicated.) >> > RISC processors often have "jump and link" rather than "call". Link and jump. > The stack > is purely conventional, it doesn't mean anything at the silicon level. That is true for some RISC processors, not for others. And even for those where a stack is not determined by the hardware, a stack is always in use in C implementations, and the choice of stack pointer register is fixed in the ABI. > "Jump and link" places the current program counter in a designated > register, then jumps to an address. Link and jump - yes, I know how it works. > So a leaf function can simply > "jump to link register" to return. A non-leaf function has to save the link > register on the stack and retrieve it. Correct. > Since caller doesn't know whether a function is leaf or not, in this case > the return address would have to be pushed by the callee. > In which case? What are you talking about? The caller never pushes the return address in RISC architectures with link-and-jump calling mechanics.
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2023-09-06 19:51 +0000 |
| Message-ID | <WK4KM.1261886$GMN3.1051401@fx16.iad> |
| In reply to | #174178 |
David Brown <david.brown@hesbynett.no> writes: >On 06/09/2023 18:37, Malcolm McLean wrote: >> On Wednesday, 6 September 2023 at 16:35:57 UTC+1, David Brown wrote: >> RISC processors often have "jump and link" rather than "call". > >Link and jump. > ARM calls it branch and link (BL). Horses for Courses.
[toc] | [prev] | [next] | [standalone]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2023-09-06 12:52 -0700 |
| Message-ID | <udal9v$2kkj4$1@dont-email.me> |
| In reply to | #174196 |
On 9/6/2023 12:51 PM, Scott Lurndal wrote: > David Brown <david.brown@hesbynett.no> writes: >> On 06/09/2023 18:37, Malcolm McLean wrote: >>> On Wednesday, 6 September 2023 at 16:35:57 UTC+1, David Brown wrote: > >>> RISC processors often have "jump and link" rather than "call". >> >> Link and jump. >> > > ARM calls it branch and link (BL). Horses for Courses. > For some reason I am now thinking about the branch delay slot over in SPARC. Never put a MEMBAR instruction in a branch delay slot!!!!!!!!!
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2023-09-07 00:36 +0100 |
| Message-ID | <87il8mq3ft.fsf@bsb.me.uk> |
| In reply to | #174196 |
scott@slp53.sl.home (Scott Lurndal) writes: > David Brown <david.brown@hesbynett.no> writes: >>On 06/09/2023 18:37, Malcolm McLean wrote: >>> On Wednesday, 6 September 2023 at 16:35:57 UTC+1, David Brown wrote: > >>> RISC processors often have "jump and link" rather than "call". >> >>Link and jump. >> > > ARM calls it branch and link (BL). Horses for Courses. I think it goes back to the IBM System/360. That had branch and link (and branch and link register) instructions for function calling. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2023-09-06 17:06 -0700 |
| Message-ID | <86fs3qoni7.fsf@linuxsc.com> |
| In reply to | #174236 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes: > scott@slp53.sl.home (Scott Lurndal) writes: > >> David Brown <david.brown@hesbynett.no> writes: >> >>> On 06/09/2023 18:37, Malcolm McLean wrote: >>> >>>> On Wednesday, 6 September 2023 at 16:35:57 UTC+1, David Brown wrote: >>>> >>>> RISC processors often have "jump and link" rather than "call". >>> >>> Link and jump. >> >> ARM calls it branch and link (BL). Horses for Courses. > > I think it goes back to the IBM System/360. That had branch and link > (and branch and link register) instructions for function calling. I had to think for a moment before remembering that on the System/360 it was BAL and BALR.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.arthur.mclean@gmail.com> |
|---|---|
| Date | 2023-09-06 18:47 -0700 |
| Message-ID | <77451a8d-5536-455e-9eaf-3520bc261cf4n@googlegroups.com> |
| In reply to | #174178 |
On Wednesday, 6 September 2023 at 19:49:24 UTC+1, David Brown wrote: > On 06/09/2023 18:37, Malcolm McLean wrote: > > On Wednesday, 6 September 2023 at 16:35:57 UTC+1, David Brown wrote: > >> On 06/09/2023 16:53, Malcolm McLean wrote: > >>> On Wednesday, 6 September 2023 at 15:08:56 UTC+1, David Brown wrote: > >>>> Bart > >>> > >>>> I'd have been happy to see C defined in a way that makes it undefined > >>>> behaviour if a non-void function reaches the terminating close brace. I > >>>> would not have been happy to see it defined to require a "return expr" > >>>> statement in non-void functions, because I think these things should be > >>>> about the behaviour of functions, not their syntax. But I personally > >>>> don't see the current standard rules here as a big issue, because they > >>>> rule out misuse (you are not allowed to attempt to use the value of > >>>> falling off the end of a non-void function), and they do not force > >>>> programmers to write code that is never executed. It is all very simple > >>>> and natural in terms of how functions and calls are typically implemented. > >>>> > >>> The way some other languages do it is to have a special variable which is > >>> the return value. (Often it has the same name as the function). That variable > >>> is the returned whne the function exits. So it's not possible to write a function > >>> that returns nothing on some control paths. > >> That's true. But it is still entirely possible to return nonsense. > >> Some languages will choose to initialise the return variable to a > >> default dummy value, making that a minimum return value. I've never > >> been a fan of that idea - such defaults are often incorrect and invalid > >> for the specification of the function, and I'd rather have compiler > >> warnings about missing return values (just as I'd rather not have local > >> variables be default initialised). > >> > >> No matter how a programming language defines these things, there are no > >> general methods to guarantee that the function returns the correct value > >> (or /a/ correct value, if there are several possibilities) according to > >> its requirements. And if it is not going to return a correct value, why > >> fuss about what it does or does not return - the code is buggy. The > >> best a language and/or tool can do is tell you when you are likely, > >> according to common practices, to have made a mistake. C compilers do > >> that just as well as Pascal compilers do, or other languages that have a > >> special return variable. > >>>> > >>>> > >>>> Tool vendors know their audience and their needs - the needs of > >>>> someone coding a little game on Windows, those of someone making a > >>>> rocket engine controller, and those of someone maintaining 40 year old > >>>> code are totally different. > >>>> > >>> Yes, but no-one wants "functions" which sometimes return a value and sometimes > >>> don't. > >> Really? Do you speak for all programmers here? Ben gave an example > >> earlier of a function that has a non-void return type, but which will > >> never return any value because it never returns. > >> > >> I'll accept that in almost all cases, you either want to be sure that a > >> function returns the correct value, or that you have some way of knowing > >> that you have a good return value. Many modern languages have natural > >> support for that - a Python function might return a value or None, a C++ > >> function might return a std::optional<>, and other languages have ways > >> of indicating success or failure. I think it is rare to find uses for > >> functions where you might get a valid return, or might not, and have no > >> clear way of determining the case. > >>> In a little game no real harm can be done, whilst in a rocket engine > >>> contoller an expensive rocket might blow up, but it's the same bug. > >> People writing rocket engine controllers know how to to use their tools > >> and high quality development processes - such bugs will never occur in > >> their code, regardless of the language used. > >>>> > >>>>> Assuming it doesn't affect the mechanics of how function calls work in > >>>>> the target. A stack-based target /must/ push some return value, > >>>>> otherwise it'll interpret some wrong value as the return address. > >>>>> > >>>> I could only imagine this happing in a C implementation on a machine > >>>> that has separate return and data stacks - I don't know any such > >>>> systems, but they could hypothetically exist. The solution there would > >>>> be to push a fake return value (perhaps all zeros, perhaps random). > >>>> > >>>> In more common single-stack systems, return values are either in > >>>> registers, or in stack space allocated by the caller, not the callee. > >>>> > >>> There are two ways of doing it on a single stack-based system. > >>> The first is to push the arguments in caller, then push a dummy value > >>> for the return value, which is later filled in by the callee. The other way > >>> is to push just the arguments, and make the callee push the return value. > >> In theory, there are many ways these things can be done. In practice, > >> there are very few that make sense on most processors. Your second > >> method here is never used in reality. For general processors, return > >> values are either in registers, or the caller allocates space on the > >> stack before calling. A pointer to this space may be passed as a hidden > >> parameter, or the callee may find it implicitly as a fixed offset from > >> the stack pointer. (If the size is unknown, as might be the case in a > >> dynamically typed language, the actual return value will be a fixed-size > >> pointer or proxy object of some kind.) For some very small CISC > >> microcontrollers, return values can be placed in specific fixed > >> addresses in ram. > >> > >> It makes no sense for a function to push a return value, because then it > >> could no longer use a "return" assembly instruction - you need the > >> return address will be at the top of the stack. It would not be > >> /impossible/ to dig the return address out the stack and do an indirect > >> jump, but doing so would be extra complications, break C ABI's, and > >> undermine the hardware accelerations and optimisations that modern > >> processors have to make "return" instructions as fast as possible. > >> (RISC processors generally have more flexibility for return addresses, > >> but much of the same logic still applies - and it would make C ABI's > >> more complicated.) > >> > > RISC processors often have "jump and link" rather than "call". > Link and jump. > > The stack > > is purely conventional, it doesn't mean anything at the silicon level. > That is true for some RISC processors, not for others. And even for > those where a stack is not determined by the hardware, a stack is always > in use in C implementations, and the choice of stack pointer register is > fixed in the ABI. > > "Jump and link" places the current program counter in a designated > > register, then jumps to an address. > Link and jump - yes, I know how it works. > > So a leaf function can simply > > "jump to link register" to return. A non-leaf function has to save the link > > register on the stack and retrieve it. > Correct. > > Since caller doesn't know whether a function is leaf or not, in this case > > the return address would have to be pushed by the callee. > > > In which case? What are you talking about? > > The caller never pushes the return address in RISC architectures with > link-and-jump calling mechanics. > No, but if callee is not leaf, then unless you've got a weird and wonderful ABI, the same register will be used for the link and jump to callee's subroutine. So it has to be saved, then retrieved when callee returns. Except for leaf functions, you do have a list of return addresses on the stack, but they are managed by callee, not caller. So, to go back to the original point, there's no particular reason the stack space for the return type has to be managed by the caller. If you're on hardware which has a hardware stack and a "ret" instruction that means "pop the stack and jump to the address you just popped" then yes, I take your point. Having caller allocate space for the return value will save you an instruction.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2023-09-07 11:11 +0200 |
| Message-ID | <udc434$2uajl$1@dont-email.me> |
| In reply to | #174251 |
On 07/09/2023 03:47, Malcolm McLean wrote:
> On Wednesday, 6 September 2023 at 19:49:24 UTC+1, David Brown wrote:
>> On 06/09/2023 18:37, Malcolm McLean wrote:
>>> On Wednesday, 6 September 2023 at 16:35:57 UTC+1, David Brown wrote:
>>>> On 06/09/2023 16:53, Malcolm McLean wrote:
>>> So a leaf function can simply
>>> "jump to link register" to return. A non-leaf function has to save the link
>>> register on the stack and retrieve it.
>> Correct.
>>> Since caller doesn't know whether a function is leaf or not, in this case
>>> the return address would have to be pushed by the callee.
>>>
>> In which case? What are you talking about?
>>
>> The caller never pushes the return address in RISC architectures with
>> link-and-jump calling mechanics.
>>
> No, but if callee is not leaf, then unless you've got a weird and wonderful ABI,
> the same register will be used for the link and jump to callee's subroutine.
Yes.
> So it has to be saved, then retrieved when callee returns.
Yes. It can save it on the stack, or in a call-preserved register.
This is exactly the same as a caller must do for any volatile registers
(registers that the ABI says the called function can change).
>
> Except for leaf functions, you do have a list of return addresses on the stack,
> but they are managed by callee, not caller.
OK (though they don't have to be on the stack).
>
> So, to go back to the original point, there's no particular reason the stack space
> for the return type has to be managed by the caller.
It is /possible/ for the stack space for large return types to be
allocated by the callee, both on CISC architectures and RISC with
link-and-jump (or whatever variant name a particular architecture uses).
And it is definitely easier on link-and-jump architectures. But it is
not done in practice - it is simpler and more consistent to use
callee-allocated stack space with C ABI's. (Of course the norm is to
use a register, or possibly several registers, unless the return type is
too big.)
I'm not arguing that callee-allocated return stack space is not
possible, merely that it is not done.
>
> If you're on hardware which has a hardware stack and a "ret" instruction that
> means "pop the stack and jump to the address you just popped" then yes,
> I take your point. Having caller allocate space for the return value will save
> you an instruction.
It will save you a lot more than a single instruction - it will be very
significantly faster, especially on "polished turd" systems like modern
x86-64 processors.
Feel free to look up ABI's for different RISC architectures, and see if
you can find one where there is callee-allocated returns on the stack
for large objects. The ones I have looked at in detail (mostly
targeting embedded RISC systems, such as ARM EABI and PPC EABI)
Another option would be to go to <https://godbolt.org> and try it out on
some of the many architectures supported there. See if you can find one
where "caller_source" does not start by allocating 1000 (or a little
more) bytes on the stack before calling "source()".
typedef struct Big {
unsigned char data[1000];
} Big;
extern Big source(void);
extern void sink(Big b);
extern Big eb;
void caller_source(void) {
Big b = source();
eb = b;
}
void caller_sink(void) {
Big b = eb;
sink(b);
}
Big callee_source(void) {
Big b = eb;
return b;
}
void callee_sink(Big b) {
eb = b;
}
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.arthur.mclean@gmail.com> |
|---|---|
| Date | 2023-09-07 04:04 -0700 |
| Message-ID | <3398dc72-084a-4ebb-8c8d-2073c62151c4n@googlegroups.com> |
| In reply to | #174301 |
On Thursday, 7 September 2023 at 10:11:17 UTC+1, David Brown wrote: > On 07/09/2023 03:47, Malcolm McLean wrote: > > > If you're on hardware which has a hardware stack and a "ret" instruction that > > means "pop the stack and jump to the address you just popped" then yes, > > I take your point. Having caller allocate space for the return value will save > > you an instruction. > It will save you a lot more than a single instruction - it will be very > significantly faster, especially on "polished turd" systems like modern > x86-64 processors. > CALLER_ALLOCATED. write return to stack. ret (pop stack and jump to address popped, in one instruction). CALLEE_ALLOCATED pop stack, and put result in register X push return onto stack jump to address in register X I make that one instruction saved for CALLER_ALLOCATED.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2023-09-07 13:24 +0200 |
| Message-ID | <udcbth$2vb0u$1@dont-email.me> |
| In reply to | #174309 |
On 07/09/2023 13:04, Malcolm McLean wrote: > On Thursday, 7 September 2023 at 10:11:17 UTC+1, David Brown wrote: >> On 07/09/2023 03:47, Malcolm McLean wrote: >> >>> If you're on hardware which has a hardware stack and a "ret" instruction that >>> means "pop the stack and jump to the address you just popped" then yes, >>> I take your point. Having caller allocate space for the return value will save >>> you an instruction. >> It will save you a lot more than a single instruction - it will be very >> significantly faster, especially on "polished turd" systems like modern >> x86-64 processors. >> > CALLER_ALLOCATED. > > write return to stack. > ret (pop stack and jump to address popped, in one instruction). > > CALLEE_ALLOCATED > > pop stack, and put result in register X > push return onto stack > jump to address in register X > > I make that one instruction saved for CALLER_ALLOCATED. I don't care how many instructions you think it saves - especially in the completely unrealistic situation of a return value that can be pushed directly to the stack. (If the return data fits in a register, it will be returned in a register - not the stack.) The /time/ difference is very different, because the hardware on these kinds of processors is heavily geared towards return calls. There are dedicated return stack buffers for the purpose, pre-fetching and speculative execution that all work on the basis of normal ABI's with normal returns. You throw all that out by having a pointless upside-down and non-standard ABI for return values. Perhaps for some languages it would make more sense to have callee allocation of return values on a stack (though none that I can think of, except perhaps Forth) - but not for C. Not on RISC architectures, and certainly not on CISC systems. Can we now leave this be? It is not relevant to C, not helpful to the discussion, and your hypothetical speculation is going nowhere. I claim that no C ABI's have callee allocation of return values on the stack. Prove me wrong and I will happily apologise, and be glad to learn something new. Until then, please drop this.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2023-09-06 18:13 +0100 |
| Message-ID | <udac0c$2j66m$1@dont-email.me> |
| In reply to | #174145 |
On 06/09/2023 15:08, David Brown wrote:
> On 05/09/2023 23:05, Bart wrote:
>> So my main disagreement is with the Optional return of non-void
>> functions (which I've now given up on), and how seriously
>> infringements of those 'N' cases are reported.
>
> Just to be clear here - and I /really/ hope you will answer this one
> simply and unambiguously - do you understand that the C standards make
> the return statement optional?
I understand they were obliged to do so for historical reasons.
I also understand that a compiler can choose to make it compulsory for
non-void functions.
> rule out misuse (you are not allowed to attempt to use the value of
> falling off the end of a non-void function),
But you very easily can. Whereas in my language, it is not possible.
> This all follows a common pattern for C - the standards define what
> useful and meaningful code does, but do not attempt to enforce good
> programming practice, since that varies hugely for different use-cases.
> It is up to tools to aid users in their development, not the C language.
> Tool vendors know their audience and their needs - the needs of
> someone coding a little game on Windows, those of someone making a
> rocket engine controller, and those of someone maintaining 40 year old
> code are totally different. And the preferences for different
> programmers vary wildly. Since most tools are targeted at many
> different people and coding styles, they support options to let users
> decide what they need. Other tools are more specialised - specific
> checkers for the Linux kernel, MISRA rule checkers for the automotive
> industry, and so on.
MISRA tries to tame the wild possibilities of C, and suggests not using
features that are troublesome or error prone.
A lot of the problems with implementing C (see my other comments below)
are because so much diversity as been allowed, and rarely deprecated.
>> Assuming it doesn't affect the mechanics of how function calls work in
>> the target. A stack-based target /must/ push some return value,
>> otherwise it'll interpret some wrong value as the return address.
>>
>
> I could only imagine this happing in a C implementation on a machine
> that has separate return and data stacks - I don't know any such
> systems, but they could hypothetically exist. The solution there would
> be to push a fake return value (perhaps all zeros, perhaps random).
>
> In more common single-stack systems, return values are either in
> registers, or in stack space allocated by the caller, not the callee.
In my new C compiler, this function:
char* getversion(void) {
return "0.99";
}
generates this IR for a stack-based virtual machine:
getversion:
load "0.99"
jump #4 (optimised out later)
#4:
retfn
'load' actually means 'push' (to avoid endless confusion with hardware
'push' instructions of the target).
So something is expected on the virtual stack. If that return statement
is commented out, it generates:
getversion:
retfn
The stacked return value is missing. This eventully gets turned into
register-based code, but that there is a missing operand will cause an
issue.
One of my languages generates a discrete IL that is an actual
independent language. The equivalent program /with/ the return produces
this:
proc $t.getversion
rettype u64
loadimm u64 "0.99.1"
return
end
Again, 'loadimm' pushes a value. I can run this via a separate
interpreter which uses an actual stack. If I comment out that 'loadimm'
line (as I can't do it in the HLL), it won't crash (it's an interpreter)
but it detects an error and aborts, as the instruction pointer gets
screwed up.
It's a bigger deal than you're making out. C is supposed to run on a
wide range of architectures - but not if they are stack-based?
>> 99% of the work is nothing to do with the standard. It's a slog. A lot
>> of it caused by so much diversity in all the C code out there,
>> /because/ people have too much freedom to write what they like.
>>
>
> The standard is what defines the language. How could it not be important?
Anyone who tries to implement C will know most of C. They might use the
grammar in the standard to design their lexers and parsers around. That
is the easy bit. (I notice it gives very little guidance regarding the
preprocessor: I have seen a 100-page reference which goes into a lot
more detail. But I came across it years too late.)
Most of it is the usual palaver of writing compilers: type-checking,
generating code, providing standard headers, maybe a library, plus, for
C, one more thing: making it work with billions of lines of existing code.
Code that flouts every rule in the book. That dwarfs everything else,
can take many years, and might never end.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2023-09-06 21:17 +0200 |
| Message-ID | <udaj7e$2kag1$1@dont-email.me> |
| In reply to | #174173 |
On 06/09/2023 19:13, Bart wrote:
> On 06/09/2023 15:08, David Brown wrote:
>> On 05/09/2023 23:05, Bart wrote:
>
>>> So my main disagreement is with the Optional return of non-void
>>> functions (which I've now given up on), and how seriously
>>> infringements of those 'N' cases are reported.
>>
>> Just to be clear here - and I /really/ hope you will answer this one
>> simply and unambiguously - do you understand that the C standards make
>> the return statement optional?
>
> I understand they were obliged to do so for historical reasons.
So that's a yes?
(I think "historical reasons" are likely a major reason for this, but I
don't think that is the whole story.)
>
> I also understand that a compiler can choose to make it compulsory for
> non-void functions.
If the compiler is not trying to implement standard C, then yes, that is
the case. A conformant compiler, however, must accept code that follows
the syntax and constraint rules of the language and has well-defined
meaning - and non-void functions without return statements can be part
of such code. (It can warn about the potential problems of such code,
while remaining conformant - but it must accept the code and generate
appropriate object code.)
>
>> rule out misuse (you are not allowed to attempt to use the value of
>> falling off the end of a non-void function),
>
> But you very easily can. Whereas in my language, it is not possible.
In your language, just as in any language, misuse - bugs - are not
difficult to write. To be clear, I am all in favour of stricter
languages and minimising the risk of accidental errors in code (that's
why I use a strict subset of C in my C coding). And if I were creating
a new language, I would not allow the possibility of running of the end
of a non-void function. (Functions which do not return at all would not
need an artificial return statement.) But in reality, the chances of
accidentally introducing such a missing return bug in C code are
extremely small - you need not only to write the bad code, but you also
need to be incompetent at basic software development practices (such as
using static checking).
>
>> This all follows a common pattern for C - the standards define what
>> useful and meaningful code does, but do not attempt to enforce good
>> programming practice, since that varies hugely for different
>> use-cases. It is up to tools to aid users in their development, not
>> the C language. Tool vendors know their audience and their needs -
>> the needs of someone coding a little game on Windows, those of someone
>> making a rocket engine controller, and those of someone maintaining 40
>> year old code are totally different. And the preferences for
>> different programmers vary wildly. Since most tools are targeted at
>> many different people and coding styles, they support options to let
>> users decide what they need. Other tools are more specialised -
>> specific checkers for the Linux kernel, MISRA rule checkers for the
>> automotive industry, and so on.
>
> MISRA tries to tame the wild possibilities of C, and suggests not using
> features that are troublesome or error prone.
>
That's roughly correct, in theory. In practice, some of the rules in
MISRA are good ideas, many are blindingly obvious to anyone qualified to
write code, some are based on mixed up misunderstandings of C and will
get you in trouble if you follow MISRA's advice, and some are downright
bad practice that lead to worse code and a higher risk of errors. I am
not at all a fan of MISRA - it's as much about legal arse-covering as
writing safer software.
But of course it is a good idea to limit the way you write your C code,
for many reasons.
> A lot of the problems with implementing C (see my other comments below)
> are because so much diversity as been allowed, and rarely deprecated.
>
I don't see that as a major problem for implementing C, although I can
well imagine some things would be easier (such as the preprocessor) if
there had been a little less flexibility. It can be a problem when
dealing with C code, however - C is sometimes written in a way that is
very difficult to follow.
>>> Assuming it doesn't affect the mechanics of how function calls work
>>> in the target. A stack-based target /must/ push some return value,
>>> otherwise it'll interpret some wrong value as the return address.
>>>
>>
>> I could only imagine this happing in a C implementation on a machine
>> that has separate return and data stacks - I don't know any such
>> systems, but they could hypothetically exist. The solution there
>> would be to push a fake return value (perhaps all zeros, perhaps random).
>
>>
>> In more common single-stack systems, return values are either in
>> registers, or in stack space allocated by the caller, not the callee.
>
>
> In my new C compiler, this function:
>
> char* getversion(void) {
> return "0.99";
> }
>
> generates this IR for a stack-based virtual machine:
>
> getversion:
> load "0.99"
> jump #4 (optimised out later)
> #4:
> retfn
>
> 'load' actually means 'push' (to avoid endless confusion with hardware
> 'push' instructions of the target).
OK.
>
> So something is expected on the virtual stack. If that return statement
> is commented out, it generates:
>
> getversion:
> retfn
There's your problem. That will almost certainly be invalid (unless you
have a very odd ABI, or more steps in your code generation sequence to
add a "push"). But that's all a problem with your code generator, not
with the way C is defined.
I would suggest that a better IR would give :
getversion :
move return_reg, "0.99"
ret
If the C "return" statement is commented out, you just have :
getversion :
ret
The returned value is always returned in the register "return_reg". If
the function doesn't have a "return expr" statement, it will not put
anything into that register - it contains old, invalid or random data.
This is not a problem if the calling code does not use it.
An alternative method is to create a local variable called
"return_value" at the entry to any non-void function. Then your IRs
become :
getversion :
local return_value (char *)
assign return_value, "0.99"
ret
and
getversion :
local return_value (char *)
ret
The return value slot is always created and returned in the same way.
But in the second case, nothing is assigned to it.
>
> The stacked return value is missing. This eventully gets turned into
> register-based code, but that there is a missing operand will cause an
> issue.
>
> One of my languages generates a discrete IL that is an actual
> independent language. The equivalent program /with/ the return produces
> this:
>
> proc $t.getversion
> rettype u64
> loadimm u64 "0.99.1"
> return
> end
>
> Again, 'loadimm' pushes a value. I can run this via a separate
> interpreter which uses an actual stack. If I comment out that 'loadimm'
> line (as I can't do it in the HLL), it won't crash (it's an interpreter)
> but it detects an error and aborts, as the instruction pointer gets
> screwed up.
>
> It's a bigger deal than you're making out. C is supposed to run on a
> wide range of architectures - but not if they are stack-based?
As I showed above, this is not a problem unless you have actively chosen
to make it a problem. But you do need to make your IR fit the language
as it is defined.
>
>>> 99% of the work is nothing to do with the standard. It's a slog. A
>>> lot of it caused by so much diversity in all the C code out there,
>>> /because/ people have too much freedom to write what they like.
>>>
>>
>> The standard is what defines the language. How could it not be
>> important?
>
> Anyone who tries to implement C will know most of C. They might use the
> grammar in the standard to design their lexers and parsers around. That
> is the easy bit. (I notice it gives very little guidance regarding the
> preprocessor: I have seen a 100-page reference which goes into a lot
> more detail. But I came across it years too late.)
The details in the C standard are a bit terse, and they are certainly
not designed as a tutorial on implementing a preprocessor (or C
compiler) - they are not even intended as a tutorial on using the
language. But they are, to my knowledge, complete.
>
> Most of it is the usual palaver of writing compilers: type-checking,
> generating code, providing standard headers, maybe a library, plus, for
> C, one more thing: making it work with billions of lines of existing code.
>
> Code that flouts every rule in the book. That dwarfs everything else,
> can take many years, and might never end.
>
Certainly the strange corner cases of any language are hard to test.
Even with the biggest and most popular compilers, people occasionally
find odd code samples that reveal bugs or limitations in the compiler.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2023-09-06 22:24 +0100 |
| Message-ID | <udaqli$2lei3$1@dont-email.me> |
| In reply to | #174180 |
On 06/09/2023 20:17, David Brown wrote:
> On 06/09/2023 19:13, Bart wrote:
>> So something is expected on the virtual stack. If that return
>> statement is commented out, it generates:
>>
>> getversion:
>> retfn
>
> There's your problem. That will almost certainly be invalid (unless you
> have a very odd ABI, or more steps in your code generation sequence to
> add a "push"). But that's all a problem with your code generator, not
> with the way C is defined.
It highlights that the problem is deeper than it looks. There is
something malformed about the function, since at the common return
point, some paths to that point won't have a pushed return value.
It's similar to trying to do this in C:
x = (a ? b);
x = (a ? b :)
When a is false, what do you store in x? Surely you wouldn't use any old
rubbish that was lying around. But here, the type system would object
even if the malformed syntax could be sorted. That is the approach I use.
> The returned value is always returned in the register "return_reg".
But I've a chosen a stack-based IR (register- or temp-based IRs are
harder to work with).
> An alternative method is to create a local variable called
> "return_value" at the entry to any non-void function. Then your IRs
> become :
>
> getversion :
> local return_value (char *)
> assign return_value, "0.99"
> ret
>
> and
>
> getversion :
> local return_value (char *)
> ret
>
> The return value slot is always created and returned in the same way.
> But in the second case, nothing is assigned to it.
Yes, this can work; you just have the extra headache of removing those
extraneous loads and stores.
(On actual stack-based bytecode for a dynamic language, I reserve a
zeroed stack slot for a return value. This allows functions to be called
via references, without knowing if they are functions or procedures. A
return value is always available in either case.
With static code you don't expect to do that.)
Although this can still leave the return value undefined even if the
mechanism is sorted. You might say, you can do this anyway:
int x;
return x;
But unitialised locals is a different subject.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2023-09-07 11:37 +0200 |
| Message-ID | <udc5kl$2uj22$1@dont-email.me> |
| In reply to | #174220 |
On 06/09/2023 23:24, Bart wrote:
> On 06/09/2023 20:17, David Brown wrote:
>> On 06/09/2023 19:13, Bart wrote:
>
>>> So something is expected on the virtual stack. If that return
>>> statement is commented out, it generates:
>>>
>>> getversion:
>>> retfn
>>
>> There's your problem. That will almost certainly be invalid (unless
>> you have a very odd ABI, or more steps in your code generation
>> sequence to add a "push"). But that's all a problem with your code
>> generator, not with the way C is defined.
>
> It highlights that the problem is deeper than it looks. There is
> something malformed about the function, since at the common return
> point, some paths to that point won't have a pushed return value.
I'm sorry, but you are completely wrong here. C defines what can be in
a function, and what the statements and expressions mean - if the C
syntax and constraint rules are followed, then by definition the code is
/not/ malformed. It may not be what you expect to see in a typical
function, but it is not malformed. And if you are making a C compiler,
you need to be able to handle this situation.
If you want to make a C compiler, you have to make a compiler for /C/.
You can't make a compiler for what you personally think C should be.
Well, of course you /can/ do that - but its usage will be limited. If
you only need it to compile, say, C code generated by your other
transpilers, then that's fine. If you want to limit your compiler to a
certain subset of C, or add extensions, then that's also okay - but
please document these features if you expect others to use it, and make
it clear that your compiler is not a conforming standard C compiler.
You can then compare it to other C compilers and claim "my compiler is
better for my uses because it does this" - but don't claim "other
compilers are wrong because mine does this".
>
> It's similar to trying to do this in C:
>
> x = (a ? b);
> x = (a ? b :)
>
> When a is false, what do you store in x? Surely you wouldn't use any old
> rubbish that was lying around. But here, the type system would object
> even if the malformed syntax could be sorted. That is the approach I use.
>
These expressions are not allowed in C, so it doesn't make a lot of
sense to talk about them or compare them to anything.
You could, if you wanted to, define a meaning to them as extensions.
Two obvious choices would be :
x = a ? b : x;
and
if (a) x = b;
These are normal C statement expressions and should be fine to implement.
>
>> The returned value is always returned in the register "return_reg".
>
> But I've a chosen a stack-based IR (register- or temp-based IRs are
> harder to work with).
OK.
But if you find the IR structure you have chosen makes it difficult to
implement the C language, then surely the issue is with that choice of
IR? You don't get to blame C for the internal choices /you/ made for
/your/ implementation!
You can happily say that your IR works well with some other languages
(your own languages, or other defined languages) - different IR setups
will be suitable for different languages, and one should not expect a
"one size fits all" solution. You can say you'd have preferred C to
have been defined differently. But your choice of implementation
details are your own.
>
>> An alternative method is to create a local variable called
>> "return_value" at the entry to any non-void function. Then your IRs
>> become :
>>
>> getversion :
>> local return_value (char *)
>> assign return_value, "0.99"
>> ret
>>
>> and
>>
>> getversion :
>> local return_value (char *)
>> ret
>>
>> The return value slot is always created and returned in the same way.
>> But in the second case, nothing is assigned to it.
>
> Yes, this can work; you just have the extra headache of removing those
> extraneous loads and stores.
I would not imagine it is a headache. Either your tool already has
optimisations to remove extra loads and stores, in which case one more
to remove doesn't matter, or it does not, in which case one more left in
doesn't matter. (You are targeting x86 - modern x86 processors are
really good at removing extra register movements in the hardware.)
>
> (On actual stack-based bytecode for a dynamic language, I reserve a
> zeroed stack slot for a return value. This allows functions to be called
> via references, without knowing if they are functions or procedures. A
> return value is always available in either case.
>
> With static code you don't expect to do that.)
>
> Although this can still leave the return value undefined even if the
> mechanism is sorted. You might say, you can do this anyway:
>
> int x;
> return x;
>
> But unitialised locals is a different subject.
>
That would be fine, as far as I can see - if the callee function runs
off the end, and the caller tries to use the return value, the
programmer can't expect any sensible results. It's all undefined
behaviour. So it doesn't matter what value is "returned" in this case.
But as final suggestion, how about you transform any non-void function
like this:
return_type foo(parameters...) {
// Do stuff
// Possibly return, possibly not
}
into :
return_type foo(parameters...) {
// Do stuff
// Possibly return, possibly not
return_type _missing_return;
return _missing_return;
}
Inject these two statements into the end of all non-void functions (or
possibly all non-void functions that do not have a "return" statement as
their final statement). Suddenly all your problems disappear.
And if you have dead-code elimination optimisations, that code gets
temporarily created and then removed. If you don't have such
optimisations, the worst that happens is the object code is marginally
bigger.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2023-09-07 11:53 +0100 |
| Message-ID | <udca3j$2v7hg$1@dont-email.me> |
| In reply to | #174303 |
On 07/09/2023 10:37, David Brown wrote:
> On 06/09/2023 23:24, Bart wrote:
[Missing 'return value;']
> But as final suggestion, how about you transform any non-void function
> like this:
>
> return_type foo(parameters...) {
> // Do stuff
> // Possibly return, possibly not
> }
>
> into :
>
> return_type foo(parameters...) {
> // Do stuff
> // Possibly return, possibly not
>
> return_type _missing_return;
> return _missing_return;
> }
>
> Inject these two statements into the end of all non-void functions (or
> possibly all non-void functions that do not have a "return" statement as
> their final statement). Suddenly all your problems disappear.
I've already suggested a compiler should return all-zeros as a default
return value for code that runs into the final '}'. That will provide a
consistent return value.
That helps with this compilation. The issue will still exist in the
source code however, and with another compiler, things can be different.
Making this a compile error would literally be fixing it at source.
> And if you have dead-code elimination optimisations, that code gets
> temporarily created and then removed. If you don't have such
> optimisations, the worst that happens is the object code is marginally
> bigger.
This is exactly the argument you can apply by insisting the user writes
an explicit 'return 0;' for example at the end of a non-void function,
if a compiler reports that one might be needed.
This will fix any potential problems once and for all across all
compilers, dialects and options.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2023-09-07 13:33 +0200 |
| Message-ID | <udccdg$2vb0u$2@dont-email.me> |
| In reply to | #174308 |
On 07/09/2023 12:53, Bart wrote:
> On 07/09/2023 10:37, David Brown wrote:
>> On 06/09/2023 23:24, Bart wrote:
>
> [Missing 'return value;']
>
>> But as final suggestion, how about you transform any non-void function
>> like this:
>>
>> return_type foo(parameters...) {
>> // Do stuff
>> // Possibly return, possibly not
>> }
>>
>> into :
>>
>> return_type foo(parameters...) {
>> // Do stuff
>> // Possibly return, possibly not
>>
>> return_type _missing_return;
>> return _missing_return;
>> }
>>
>> Inject these two statements into the end of all non-void functions (or
>> possibly all non-void functions that do not have a "return" statement
>> as their final statement). Suddenly all your problems disappear.
>
> I've already suggested a compiler should return all-zeros as a default
> return value for code that runs into the final '}'. That will provide a
> consistent return value.
If you like, you can do that. I personally don't see that as an
advantage for how I use C (as you know, I am happy to see a number of
things undefined or unspecified). But if you do, I have no problem with
that, and I see no conflict with the C standards if you choose to
implement things that way.
>
> That helps with this compilation. The issue will still exist in the
> source code however, and with another compiler, things can be different.
If the code has defined behaviour (i.e., the function may be called, but
its non-existent return value is not used), then the results will be the
same. If the code has undefined behaviour (by trying to use the value),
the results could be different. This is exactly as you would normally
expect when different compilers are faced with code with undefined
behaviour - there are no guarantees or even expectations of getting the
same results, and you should not worry about that.
> Making this a compile error would literally be fixing it at source.
But it is not an error in the source - not in standard C.
I still think it is good if your compiler gives at least a warning, and
perhaps an error, as an option or even by default. But if you want your
tool to be a conforming C compiler, in at least some modes, then you
have to accept such code and compile it with the behaviour dictated by
the C standards.
>
>
>> And if you have dead-code elimination optimisations, that code gets
>> temporarily created and then removed. If you don't have such
>> optimisations, the worst that happens is the object code is marginally
>> bigger.
>
> This is exactly the argument you can apply by insisting the user writes
> an explicit 'return 0;' for example at the end of a non-void function,
> if a compiler reports that one might be needed.
>
> This will fix any potential problems once and for all across all
> compilers, dialects and options.
>
No, not at all.
For one thing, some compilers might warn about the useless code of
adding an unreachable "return 0;". Secondly, some programmers or code
reviewers might complain about it - I certainly would.
Adding "return 0;" to the user code is a user-visible change and a user
requirement. This makes it vastly more costly, in many senses of the
word, than a hidden internal change inside the implementation.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2023-09-07 14:36 -0700 |
| Message-ID | <875y4l3buk.fsf@nosuchdomain.example.com> |
| In reply to | #174308 |
Bart <bc@freeuk.com> writes:
[...]
> I've already suggested a compiler should return all-zeros as a default
> return value for code that runs into the final '}'. That will provide
> a consistent return value.
That could mask bugs.
int func(void) {
if (this) {
return a_value;
}
else if (that) {
return another_value;
}
else if (the_other) {
return yet_another_value;
}
}
Perhaps I simply forgot to write a return statement at the end, either
before the closing } or in an else clause. Currently, a compiler is not
required to diagnose this, but many will warn about it with the right
options. If the language stated that falling off the end implicitly
returns "all-zeros" (I won't get into what that means), then the behavior
is well defined and the compiler is unlikely to be able to help.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
Page 7 of 18 — ← Prev page 1 … 5 6 [7] 8 9 … 18 Next page →
Back to top | Article view | comp.lang.c
csiph-web