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


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

switch/extension for see below strongly needed

Started byfir <profesor.fir@gmail.com>
First post2026-05-17 00:03 +0200
Last post2026-05-27 01:05 +0000
Articles 20 on this page of 245 — 19 participants

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


Contents

  switch/extension for see below strongly needed fir <profesor.fir@gmail.com> - 2026-05-17 00:03 +0200
    Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-17 01:08 +0100
      Re: switch/extension for see below strongly needed Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-05-16 18:21 -0700
        Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-17 12:16 +0100
          Re: switch/extension for see below strongly needed fir <profesor.fir@gmail.com> - 2026-05-17 15:04 +0200
            Re: switch/extension for see below strongly needed fir <profesor.fir@gmail.com> - 2026-05-17 15:08 +0200
          Re: switch/extension for see below strongly needed Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-05-17 06:48 -0700
            Re: switch/extension for see below strongly needed Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2026-05-17 14:43 +0000
              Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-17 16:53 +0100
              Re: switch/extension for see below strongly needed fir <profesor.fir@gmail.com> - 2026-05-17 18:24 +0200
                Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-17 17:56 +0100
                  Re: switch/extension for see below strongly needed fir <profesor.fir@gmail.com> - 2026-05-17 21:07 +0200
                  Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-18 08:56 +0200
                    Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-18 09:22 +0200
                      Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-18 10:35 +0200
                        Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-18 10:41 +0200
                        Re: switch/extension for see below strongly needed antispam@fricas.org (Waldek Hebisch) - 2026-05-18 16:47 +0000
                          Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-18 18:58 +0200
                            Using "extra" blocks to declare local variables (Was: switch/extension for see below strongly needed) gazelle@shell.xmission.com (Kenny McCormack) - 2026-05-19 05:48 +0000
                              Re: Using "extra" blocks to declare local variables (Was: switch/extension for see below strongly needed) David Brown <david.brown@hesbynett.no> - 2026-05-19 08:18 +0200
                                Re: Using "extra" blocks to declare local variables (Was: switch/extension for see below strongly needed) scott@slp53.sl.home (Scott Lurndal) - 2026-05-19 14:04 +0000
                                  Re: Using "extra" blocks to declare local variables (Was: switch/extension for see below strongly needed) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-05-22 23:44 -0700
                          Re: switch/extension for see below strongly needed cross@spitfire.i.gajendra.net (Dan Cross) - 2026-05-18 18:13 +0000
                            Re: switch/extension for see below strongly needed scott@slp53.sl.home (Scott Lurndal) - 2026-05-18 18:37 +0000
                            You are not allowed to use "the S word" in this ng. (Was: switch/extension for see below strongly needed) gazelle@shell.xmission.com (Kenny McCormack) - 2026-05-19 05:49 +0000
                        Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-18 18:35 +0100
                          Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-18 21:24 +0200
                            Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-18 21:48 +0100
                              Re: switch/extension for see below strongly needed Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-05-31 17:00 -0700
                          Re: switch/extension for see below strongly needed Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-05-18 14:23 -0700
                          Re: switch/extension for see below strongly needed Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-05-19 06:58 +0000
                            Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-19 11:55 +0100
                              Re: switch/extension for see below strongly needed Richard Harnden <richard.nospam@gmail.invalid> - 2026-05-19 12:15 +0100
                                Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-19 12:48 +0100
                                  Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-19 14:23 +0200
                                    Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-19 14:08 +0100
                                      Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-19 15:40 +0200
                                        Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-19 16:41 +0200
                                          Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-19 17:07 +0200
                                            Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-19 17:23 +0200
                                              Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-19 17:58 +0200
                                                Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-19 18:31 +0200
                                                  Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-19 18:38 +0200
                                                    Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-19 18:54 +0200
                                            Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-19 17:44 +0100
                                              Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-19 18:59 +0200
                                        Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-19 17:31 +0100
                                          Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-19 18:48 +0200
                                            Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-19 18:47 +0100
                                              Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-19 21:58 +0200
                                                Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-19 22:16 +0100
                                                  Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-20 08:59 +0200
                                                    Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-20 14:20 +0100
                                                      Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-20 16:22 +0200
                                                        Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-20 16:41 +0100
                                                          Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-20 19:51 +0200
                                                            Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-20 21:14 +0100
                                                              Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-21 08:45 +0200
                                                                Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-21 12:56 +0100
                                                                  Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-21 14:55 +0200
                                                                    Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-21 18:26 +0100
                                                                      Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-21 21:23 +0200
                                                                        Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-21 20:59 +0100
                                                                          Re: switch/extension for see below strongly needed cross@spitfire.i.gajendra.net (Dan Cross) - 2026-05-21 21:35 +0000
                                                                          Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-22 09:31 +0200
                                                                        Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-22 06:52 +0200
                                                                          Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-22 09:34 +0200
                                                                          Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-22 11:43 +0100
                                                                            Re: switch/extension for see below strongly needed cross@spitfire.i.gajendra.net (Dan Cross) - 2026-05-22 12:13 +0000
                                                                              Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-22 14:16 +0100
                                                                                Re: switch/extension for see below strongly needed cross@spitfire.i.gajendra.net (Dan Cross) - 2026-05-22 17:32 +0000
                                                                                  Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-22 20:27 +0100
                                                                                    Re: switch/extension for see below strongly needed cross@spitfire.i.gajendra.net (Dan Cross) - 2026-05-23 15:30 +0000
                                                                                      Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-23 17:59 +0100
                                                                              Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-23 07:56 +0200
                                                                          Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-22 11:41 +0100
                                                                            Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-22 13:31 +0200
                                                                              Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-22 13:42 +0100
                                                                                Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-22 15:11 +0200
                                                                                Re: switch/extension for see below strongly needed cross@spitfire.i.gajendra.net (Dan Cross) - 2026-05-22 14:57 +0000
                                                                                  Re: switch/extension for see below strongly needed scott@slp53.sl.home (Scott Lurndal) - 2026-05-22 16:16 +0000
                                                                                    Re: switch/extension for see below strongly needed cross@spitfire.i.gajendra.net (Dan Cross) - 2026-05-22 17:43 +0000
                                                                                      Re: switch/extension for see below strongly needed scott@slp53.sl.home (Scott Lurndal) - 2026-05-22 21:03 +0000
                                                                                        Re: switch/extension for see below strongly needed cross@spitfire.i.gajendra.net (Dan Cross) - 2026-05-22 22:02 +0000
                                                                                        Re: switch/extension for see below strongly needed Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-05-25 07:39 -0700
                                                                                  Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-22 17:53 +0100
                                                                                    Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-23 07:51 +0200
                                                                                      Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-23 10:58 +0100
                                                                                  Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-23 07:33 +0200
                                                                                    Re: switch/extension for see below strongly needed cross@spitfire.i.gajendra.net (Dan Cross) - 2026-05-24 02:48 +0000
                                                                                      Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-24 10:13 +0200
                                                                                      Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-24 12:30 +0100
                                                                                        Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-24 13:39 +0100
                                                                                        Re: switch/extension for see below strongly needed tTh <tth@none.invalid> - 2026-05-24 22:09 +0200
                                                                                          Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-24 21:48 +0100
                                                                                            Re: switch/extension for see below strongly needed scott@slp53.sl.home (Scott Lurndal) - 2026-05-24 22:04 +0000
                                                                                          Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-25 10:34 +0200
                                                                          Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-22 11:45 +0100
                                                                  Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-21 15:08 +0200
                                                                    Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-21 14:31 +0100
                                                                      Re: switch/extension for see below strongly needed Michael S <already5chosen@yahoo.com> - 2026-05-21 19:37 +0300
                                                                        Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-21 18:38 +0100
                                                                    Re: switch/extension for see below strongly needed James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-05-21 13:54 -0400
                                                                      Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-21 20:09 +0200
                                                                        Re: switch/extension for see below strongly needed Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-05-21 14:31 -0700
                                                                          Re: switch/extension for see below strongly needed James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-05-21 19:41 -0400
                                                                            Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-22 05:23 +0200
                                                                          Re: switch/extension for see below strongly needed Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-05-22 21:38 -0700
                                                                            Re: switch/extension for see below strongly needed Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-05-22 23:17 -0700
                                                                              Re: switch/extension for see below strongly needed Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-05-23 00:04 -0700
                                                                              Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-23 09:35 +0200
                                                                                Re: switch/extension for see below strongly needed Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-05-23 03:59 -0700
                                                                  Re: switch/extension for see below strongly needed James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-05-21 13:48 -0400
                                                                  Re: switch/extension for see below strongly needed Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-05-21 14:23 -0700
                                                                    Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-21 23:47 +0100
                                                                      Re: switch/extension for see below strongly needed Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-05-21 17:24 -0700
                                                                        Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-22 01:51 +0100
                                                                          Re: switch/extension for see below strongly needed scott@slp53.sl.home (Scott Lurndal) - 2026-05-22 14:04 +0000
                                                                            Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-22 16:16 +0100
                                                                              Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-22 17:47 +0200
                                                                                Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-22 17:35 +0100
                                                                                  Re: switch/extension for see below strongly needed scott@slp53.sl.home (Scott Lurndal) - 2026-05-22 20:57 +0000
                                                                                    Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-23 00:24 +0100
                                                                                  Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-23 11:46 +0200
                                                                                    Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-23 11:31 +0100
                                                                                      Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-23 13:51 +0200
                                                                                        Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-23 13:07 +0100
                                                                                          Re: switch/extension for see below strongly needed fir <profesor.fir@gmail.com> - 2026-05-23 14:35 +0200
                                                                                            Re: switch/extension for see below strongly needed fir <profesor.fir@gmail.com> - 2026-05-23 14:38 +0200
                                                                                          Re: switch/extension for see below strongly needed Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-05-23 20:46 -0700
                                                                                      Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-23 13:55 +0100
                                                                        Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-22 05:58 +0200
                                                                          Re: switch/extension for see below strongly needed Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-05-21 21:21 -0700
                                                                            Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-22 07:17 +0200
                                                                          Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-22 10:49 +0200
                                                                            Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-23 05:49 +0200
                                                                          Re: switch/extension for see below strongly needed James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-05-22 18:37 -0400
                                                                    Re: switch/extension for see below strongly needed James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-05-21 19:49 -0400
                                                                      Re: switch/extension for see below strongly needed Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-05-21 17:27 -0700
                                                                    Re: switch/extension for see below strongly needed Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-05-23 14:21 -0700
                                                                      Re: switch/extension for see below strongly needed Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-05-23 20:32 -0700
                                                                    Re: switch/extension for see below strongly needed Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-05-23 14:19 -0700
                                                                    Re: switch/extension for see below strongly needed Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-05-23 14:03 -0700
                                                      Re: switch/extension for see below strongly needed "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-05-20 16:39 -0700
                                                    Re: switch/extension for see below strongly needed cross@spitfire.i.gajendra.net (Dan Cross) - 2026-05-20 15:18 +0000
                                                      Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-20 17:38 +0200
                                                        Re: switch/extension for see below strongly needed cross@spitfire.i.gajendra.net (Dan Cross) - 2026-05-20 18:17 +0000
                                                          Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-21 09:56 +0200
                                                            Re: switch/extension for see below strongly needed cross@spitfire.i.gajendra.net (Dan Cross) - 2026-05-21 12:18 +0000
                                                              Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-21 15:16 +0200
                                                                Re: switch/extension for see below strongly needed cross@spitfire.i.gajendra.net (Dan Cross) - 2026-05-22 14:44 +0000
                                                                  Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-22 17:12 +0200
                                                                    Re: switch/extension for see below strongly needed cross@spitfire.i.gajendra.net (Dan Cross) - 2026-05-24 19:08 +0000
                                                                      Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-25 12:16 +0200
                                                                        Re: switch/extension for see below strongly needed cross@spitfire.i.gajendra.net (Dan Cross) - 2026-05-26 14:09 +0000
                                                                          Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-26 18:16 +0200
                                                                          Re: switch/extension for see below strongly needed Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-06-04 07:19 -0700
                                                                            Re: switch/extension for see below strongly needed cross@spitfire.i.gajendra.net (Dan Cross) - 2026-06-04 17:18 +0000
                                                              Re: switch/extension for see below strongly needed scott@slp53.sl.home (Scott Lurndal) - 2026-05-21 15:04 +0000
                                                      Re: switch/extension for see below strongly needed "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-05-20 16:47 -0700
                                                        Re: switch/extension for see below strongly needed cross@spitfire.i.gajendra.net (Dan Cross) - 2026-05-21 02:55 +0000
                                                      Re: switch/extension for see below strongly needed Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-05-23 21:12 -0700
                                                        Re: switch/extension for see below strongly needed Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-05-23 21:31 -0700
                                                        Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-24 11:00 +0200
                                                        Re: switch/extension for see below strongly needed Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-05-24 04:15 -0700
                                                  Re: switch/extension for see below strongly needed James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-05-20 10:40 -0400
                                                    Re: switch/extension for see below strongly needed "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-05-20 16:52 -0700
                                                  Re: switch/extension for see below strongly needed cross@spitfire.i.gajendra.net (Dan Cross) - 2026-05-20 14:56 +0000
                                            Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-20 06:38 +0200
                                              Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-21 02:45 +0200
                                                Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-21 02:31 +0100
                                                Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-21 10:16 +0200
                                                  [OT] Genie bug and fix (was Re: switch/extension for see below strongly needed) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-22 04:48 +0200
                                                    Re: [OT] Genie bug and fix (was Re: switch/extension for see below strongly needed) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-22 05:02 +0200
                                                    Re: [OT] Genie bug and fix (was Re: switch/extension for see below strongly needed) Bart <bc@freeuk.com> - 2026-05-22 11:18 +0100
                                                      Re: [OT] Genie bug and fix (was Re: switch/extension for see below strongly needed) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-23 09:21 +0200
                                          Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-20 06:24 +0200
                                            Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-20 11:55 +0100
                                              Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-21 02:30 +0200
                                                Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-21 02:21 +0100
                                                  Re: switch/extension for see below strongly needed Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-05-20 18:51 -0700
                                                    Re: switch/extension for see below strongly needed gazelle@shell.xmission.com (Kenny McCormack) - 2026-05-21 11:46 +0000
                                                      Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-21 14:56 +0200
                                                  Re: switch/extension for see below strongly needed scott@slp53.sl.home (Scott Lurndal) - 2026-05-21 15:12 +0000
                                                    Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-21 16:47 +0100
                                                    Re: switch/extension for see below strongly needed Michael S <already5chosen@yahoo.com> - 2026-05-21 19:27 +0300
                                                      Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-21 20:03 +0200
                                                        Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-21 19:42 +0100
                                                    Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-21 19:46 +0200
                                                      Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-21 20:08 +0100
                                        Re: switch/extension for see below strongly needed "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-05-19 14:34 -0700
                                          Re: switch/extension for see below strongly needed Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-05-19 15:01 -0700
                                            Re: switch/extension for see below strongly needed "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-05-19 15:15 -0700
                                              Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-20 09:24 +0200
                                                Re: switch/extension for see below strongly needed Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-05-20 03:26 -0700
                              Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-19 13:29 +0200
                                Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-19 16:46 +0200
                              Re: switch/extension for see below strongly needed scott@slp53.sl.home (Scott Lurndal) - 2026-05-19 13:56 +0000
                              Re: switch/extension for see below strongly needed Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-05-19 14:27 -0700
                          Re: switch/extension for see below strongly needed James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-05-19 12:35 -0400
                    Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-18 11:57 +0100
                      Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-18 13:57 +0200
                        Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-18 14:18 +0100
                          Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-18 16:07 +0200
                          Re: switch/extension for see below strongly needed Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-05-18 14:12 -0700
                  Re: switch/extension for see below strongly needed Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-05-18 07:17 +0000
              Re: switch/extension for see below strongly needed Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-05-17 23:30 +0000
                Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-18 09:02 +0200
                  Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-18 09:38 +0200
                    Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-18 10:50 +0100
                  Re: switch/extension for see below strongly needed fir <profesor.fir@gmail.com> - 2026-05-18 10:00 +0200
                  Re: switch/extension for see below strongly needed "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-05-18 16:31 -0700
                    Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-19 09:18 +0200
                      Re: switch/extension for see below strongly needed David Brown <david.brown@hesbynett.no> - 2026-05-19 10:00 +0200
                        Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-19 10:34 +0200
                          Re: switch/extension for see below strongly needed "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-05-19 14:19 -0700
                            Re: switch/extension for see below strongly needed Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-05-20 04:09 +0200
              Re: switch/extension for see below strongly needed James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-05-19 11:43 -0400
          Re: switch/extension for see below strongly needed cross@spitfire.i.gajendra.net (Dan Cross) - 2026-05-18 01:22 +0000
            Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-18 11:23 +0100
              Re: switch/extension for see below strongly needed cross@spitfire.i.gajendra.net (Dan Cross) - 2026-05-18 11:07 +0000
                Re: switch/extension for see below strongly needed fir <profesor.fir@gmail.com> - 2026-05-18 14:10 +0200
                  Re: switch/extension for see below strongly needed fir <profesor.fir@gmail.com> - 2026-05-18 15:01 +0200
                    Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-18 14:33 +0100
                      Re: switch/extension for see below strongly needed fir <profesor.fir@gmail.com> - 2026-05-18 16:39 +0200
                        Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-18 16:12 +0100
                          Re: switch/extension for see below strongly needed fir <profesor.fir@gmail.com> - 2026-05-18 17:35 +0200
                      Re: switch/extension for see below strongly needed fir <profesor.fir@gmail.com> - 2026-05-18 16:59 +0200
                        Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-18 16:25 +0100
                          Re: switch/extension for see below strongly needed fir <profesor.fir@gmail.com> - 2026-05-18 17:50 +0200
                            Re: switch/extension for see below strongly needed fir <profesor.fir@gmail.com> - 2026-05-18 18:21 +0200
                        Re: switch/extension for see below strongly needed fir <profesor.fir@gmail.com> - 2026-05-18 17:29 +0200
                      Re: switch/extension for see below strongly needed fir <profesor.fir@gmail.com> - 2026-05-18 17:04 +0200
                        Re: switch/extension for see below strongly needed Bart <bc@freeuk.com> - 2026-05-18 16:31 +0100
                          Re: switch/extension for see below strongly needed fir <profesor.fir@gmail.com> - 2026-05-18 18:12 +0200
                          Re: switch/extension for see below strongly needed fir <profesor.fir@gmail.com> - 2026-05-18 18:24 +0200
                      Re: switch/extension for see below strongly needed Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-05-18 14:40 -0700
      Re: switch/extension for see below strongly needed fir <profesor.fir@gmail.com> - 2026-05-17 14:57 +0200
        Re: switch/extension for see below strongly needed fir <profesor.fir@gmail.com> - 2026-05-17 16:06 +0200
    Re: multipass Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-05-17 05:50 +0000
      Re: multipass Bart <bc@freeuk.com> - 2026-05-17 11:26 +0100
        Re: multipass David Brown <david.brown@hesbynett.no> - 2026-05-18 09:08 +0200
      Re: multipass Bonita Montero <Bonita.Montero@gmail.com> - 2026-05-17 17:31 +0200
      Re: multipass makendo <makendo@makendo.invalid> - 2026-05-24 01:14 +0800
        Re: multipass Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-05-27 01:05 +0000

Page 8 of 13 — ← Prev page 1 … 6 7 [8] 9 10 … 13  Next page →


#399378

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2026-05-23 20:32 -0700
Message-ID<86pl2lfpns.fsf@linuxsc.com>
In reply to#399369
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:

> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>
>> Bart <bc@freeuk.com> writes:
>>
>>> On 21/05/2026 07:45, David Brown wrote:
>>
>> [...]
>>
>>>> So do you have an example of where code has been written to take
>>>> advantage of the separate name spaces?
>>>
>>> No.  This is why I claimed it was pointless.
>>
>> This entire discussion is pointless.  [...]
>
> I was hoping you would stop there.  Your point would have
> been made much more effectively.

Sorry for the duplicates.  News server hiccups.

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


#399370

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2026-05-23 14:19 -0700
Message-ID<86y0h9g6yj.fsf@linuxsc.com>
In reply to#399275
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

> Bart <bc@freeuk.com> writes:
>
>> On 21/05/2026 07:45, David Brown wrote:
>
> [...]
>
>>> So do you have an example of where code has been written to take
>>> advantage of the separate name spaces?
>>
>> No.  This is why I claimed it was pointless.
>
> This entire discussion is pointless. [...]

I was hoping you would stop there.  Your point would have
been made much more effectively.

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


#399372

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2026-05-23 14:03 -0700
Message-ID<86zf1pg7nx.fsf@linuxsc.com>
In reply to#399275
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

> Bart <bc@freeuk.com> writes:
>
>> On 21/05/2026 07:45, David Brown wrote:
>
> [...]
>
>>> So do you have an example of where code has been written to take
>>> advantage of the separate name spaces?
>>
>> No.  This is why I claimed it was pointless.
>
> This entire discussion is pointless. [...]

I was hoping you would stop there.  Your point would have
been made much more effectively.

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


#399228

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2026-05-20 16:39 -0700
Message-ID<10ulgo2$cme2$1@dont-email.me>
In reply to#399214
On 5/20/2026 6:20 AM, Bart wrote:
[...]

> There are lots of different qualities of general purpose C compilers, if 
> you look outside the big 3 (gcc, clang, msvc).
> 
> I used to use DMC, Pelles C, lccwin32 extensively, and still use Tiny C.

I remember conversing with you and installed all of those as well, 
already had Pelles wrt its early support for C11 threading _and_ atomic. 
For my old hash cipher. Btw, thanks for that!

[...]

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


#399218

Fromcross@spitfire.i.gajendra.net (Dan Cross)
Date2026-05-20 15:18 +0000
Message-ID<10ukjc1$edm$1@reader1.panix.com>
In reply to#399206
In article <10ujm3r$3pnbb$1@dont-email.me>,
David Brown  <david.brown@hesbynett.no> wrote:
>[snip] I have almost never had need of "goto" or labels (excluding 
>switch case labels, of course), and don't expect ever to do so in the 
>future.

While I generally try to avoid it, there are times (in C in
particular) when it really is the right tool; the inventors of C
understood that.  From the Plan 9 `fortunes` file: "If you want
to go somewhere, goto is the best way to get there. K Thompson"

Breaking out of nested loops without a lot of unnecessary
ceremony is sort of an obvious example; jumping to common error
handling code is another that is often cited (though see the
Apple, "goto fail" bug for an example of how this can go bad).

It's interesting to me that after Dijkstra's famous March 1968,
"Go To Statement Considered Harmful" letter in CACM vol 11 no 3,
language designers seemed to address the issue by identifying
the primary useful patterns of `goto` use and codifying them as
first-class constructs in new(er) languages: labeled loops (and
corresponding elaborations on `break` etc) and exceptions are
obvious, and Go's `defer` statement is a newer example.

C came a few years after Dijkstra's letter, and I'm sure they
were aware of it.  But while it inherited `break` from BCPL, the
only addition in this area is `continue`.  DMR seemed to eschew
a more complex language for one that included `goto`, presumably
because it was intended for expert programmers judicious with
its use.

Once it escaped the lab, however....

	- Dan C.

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


#399219

FromDavid Brown <david.brown@hesbynett.no>
Date2026-05-20 17:38 +0200
Message-ID<10ukkh6$2gc8$1@dont-email.me>
In reply to#399218
On 20/05/2026 17:18, Dan Cross wrote:
> In article <10ujm3r$3pnbb$1@dont-email.me>,
> David Brown  <david.brown@hesbynett.no> wrote:
>> [snip] I have almost never had need of "goto" or labels (excluding
>> switch case labels, of course), and don't expect ever to do so in the
>> future.
> 
> While I generally try to avoid it, there are times (in C in
> particular) when it really is the right tool; the inventors of C
> understood that.  From the Plan 9 `fortunes` file: "If you want
> to go somewhere, goto is the best way to get there. K Thompson"
> 

Certainly there are situations where people feel the most clear, simple, 
reliable and efficient way to handle a particular bit of code is with a 
"goto".  Fair enough.  Personally, I have almost never felt I am in that 
situation.  I can think of perhaps four reasons why I might have fewer 
goto's than some other people :

1. I stick to optimising compilers in almost all cases - some people may 
use goto rather than an extra bool flag or too, for efficiency purposes. 
  I am in the happy position of letting the compiler generate the goto's.

2. I almost never use dynamic memory, and thus don't have much use for a 
typical "goto error" idiom for handling failed malloc.

3. My code is typically not meant to be portable, so I can use things 
like gcc's "cleanup" attribute that can replace the need of "goto error" 
or other handling when breaking out of inner loops.

4. With C99 "inline" and modern tools that do inlining and other 
inter-procedural optimisations, there is often less benefit in nested 
loops that might need a multi-level break - you can split the code into 
separate functions and use "return" to break out of the middle of loops.

So I don't suggest that nobody has need of "goto", or that all "gotos" 
are bad - merely that I very rarely have use of them myself.

> Breaking out of nested loops without a lot of unnecessary
> ceremony is sort of an obvious example; jumping to common error
> handling code is another that is often cited (though see the
> Apple, "goto fail" bug for an example of how this can go bad).
> 
> It's interesting to me that after Dijkstra's famous March 1968,
> "Go To Statement Considered Harmful" letter in CACM vol 11 no 3,
> language designers seemed to address the issue by identifying
> the primary useful patterns of `goto` use and codifying them as
> first-class constructs in new(er) languages: labeled loops (and
> corresponding elaborations on `break` etc) and exceptions are
> obvious, and Go's `defer` statement is a newer example.
> 
> C came a few years after Dijkstra's letter, and I'm sure they
> were aware of it.  But while it inherited `break` from BCPL, the
> only addition in this area is `continue`.  DMR seemed to eschew
> a more complex language for one that included `goto`, presumably
> because it was intended for expert programmers judicious with
> its use.
> 
> Once it escaped the lab, however....
> 

There's more than one feature of C, and of every other programming 
language, that we'd all like to put back into Pandora's box.  Of course, 
we'd all disagree strongly on which features those are!

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


#399223

Fromcross@spitfire.i.gajendra.net (Dan Cross)
Date2026-05-20 18:17 +0000
Message-ID<10uktre$ge2$1@reader1.panix.com>
In reply to#399219
In article <10ukkh6$2gc8$1@dont-email.me>,
David Brown  <david.brown@hesbynett.no> wrote:
>On 20/05/2026 17:18, Dan Cross wrote:
>> In article <10ujm3r$3pnbb$1@dont-email.me>,
>> David Brown  <david.brown@hesbynett.no> wrote:
>>> [snip] I have almost never had need of "goto" or labels (excluding
>>> switch case labels, of course), and don't expect ever to do so in the
>>> future.
>> 
>> While I generally try to avoid it, there are times (in C in
>> particular) when it really is the right tool; the inventors of C
>> understood that.  From the Plan 9 `fortunes` file: "If you want
>> to go somewhere, goto is the best way to get there. K Thompson"
>
>Certainly there are situations where people feel the most clear, simple, 
>reliable and efficient way to handle a particular bit of code is with a 
>"goto".  Fair enough.  Personally, I have almost never felt I am in that 
>situation.  I can think of perhaps four reasons why I might have fewer 
>goto's than some other people :
>
>1. I stick to optimising compilers in almost all cases - some people may 
>use goto rather than an extra bool flag or too, for efficiency purposes. 
>  I am in the happy position of letting the compiler generate the goto's.
>
>2. I almost never use dynamic memory, and thus don't have much use for a 
>typical "goto error" idiom for handling failed malloc.
>
>3. My code is typically not meant to be portable, so I can use things 
>like gcc's "cleanup" attribute that can replace the need of "goto error" 
>or other handling when breaking out of inner loops.
>
>4. With C99 "inline" and modern tools that do inlining and other 
>inter-procedural optimisations, there is often less benefit in nested 
>loops that might need a multi-level break - you can split the code into 
>separate functions and use "return" to break out of the middle of loops.
>
>So I don't suggest that nobody has need of "goto", or that all "gotos" 
>are bad - merely that I very rarely have use of them myself.

I'm with you on almost all of these, though I find the code that
has to check a boolean or other flag in an outer loop to be hard
to read compared to the `goto` alternative often enough that I
avoid it if I can.  Of course, that's subjective.  And I might
point out that there are other categories of cleanup one might
want to do, aside from just freeing memory (in the embedded
space, perhaps clearing a flag or setting register state in some
device to reset it...).

I particularly agree with the use of a static inline to avoid
some `goto`s.  When the `goto fail` bug was announced, as an
exercise, I rewrote Apple's code to demonstrate how one might
eliminate the problematic pattern entirely:

The original was something like:

    int
    thing_that_can_fail(void)
    {
	int err = FAILURE;
        void *p = malloc(...);
	if (p == NULL)
	    goto fail;
	void *q = whatever(...);
	if (q == NULL)
	    goto fail;
	err = something(p, q);
	if (err != 0)
	    goto fail;
	err = otherthing(p, q);
	if (err != 0)
	    goto fail;
	    goto fail;
	err = thirdthing(p, q);
	if (err != 0)
	    goto fail;
	return 0;
    fail:
        if (q != NULL)
	    dispose_of_q(q);
	free(p);
	return err;
    }

But using a small `static` inline function, we can rewrite this
as two functions that separate resource allocation and whatever
else from other fallable logic:

    static inline int
    do_thing_that_can_fail(void *p, void *q)
    {
        int err = something(p, q);
        if (err != 0)
            return err;
        err = otherthing(p, q);
        if (err != 0)
            return err;
        return thirdthing(p, q);
    }

    int
    thing_that_can_fail(void)
    {
        void *p = malloc(...);
	if (p == NULL)
	    return FAILURE;
	void *q = whatever(...);
	if (q == NULL) {
            free(p);
	    return FAILURE;
	}
        int ret = do_thing_that_can_fail(p, q);
        dispose_of_q(q);
        free(p);
        return ret;
    }

The response (this was amongst a bunch of developers are my last
company) was, "yeah, but you can't _always_ do that..." and that
may be true; but you _often_ can.  Regardless, it does not
automatically follow that `goto` is the best option for dealing
with this kind of failure.  The Plan 9 kernel, for example, used
something equivalent to setjmp/longjmp and a stack of jump
buffers to provide a primitive exception handling mechanism in
that system's decidedly non-ISO dialect of C.

>> Breaking out of nested loops without a lot of unnecessary
>> ceremony is sort of an obvious example; jumping to common error
>> handling code is another that is often cited (though see the
>> Apple, "goto fail" bug for an example of how this can go bad).
>> 
>> It's interesting to me that after Dijkstra's famous March 1968,
>> "Go To Statement Considered Harmful" letter in CACM vol 11 no 3,
>> language designers seemed to address the issue by identifying
>> the primary useful patterns of `goto` use and codifying them as
>> first-class constructs in new(er) languages: labeled loops (and
>> corresponding elaborations on `break` etc) and exceptions are
>> obvious, and Go's `defer` statement is a newer example.
>> 
>> C came a few years after Dijkstra's letter, and I'm sure they
>> were aware of it.  But while it inherited `break` from BCPL, the
>> only addition in this area is `continue`.  DMR seemed to eschew
>> a more complex language for one that included `goto`, presumably
>> because it was intended for expert programmers judicious with
>> its use.
>> 
>> Once it escaped the lab, however....
>
>There's more than one feature of C, and of every other programming 
>language, that we'd all like to put back into Pandora's box.  Of course, 
>we'd all disagree strongly on which features those are!

That's the great thing about opinions: there are so many of
them!

	- Dan C.

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


#399240

FromDavid Brown <david.brown@hesbynett.no>
Date2026-05-21 09:56 +0200
Message-ID<10umdsa$hnml$1@dont-email.me>
In reply to#399223
On 20/05/2026 20:17, Dan Cross wrote:
> In article <10ukkh6$2gc8$1@dont-email.me>,
> David Brown  <david.brown@hesbynett.no> wrote:
>> On 20/05/2026 17:18, Dan Cross wrote:
>>> In article <10ujm3r$3pnbb$1@dont-email.me>,
>>> David Brown  <david.brown@hesbynett.no> wrote:
>>>> [snip] I have almost never had need of "goto" or labels (excluding
>>>> switch case labels, of course), and don't expect ever to do so in the
>>>> future.
>>>
>>> While I generally try to avoid it, there are times (in C in
>>> particular) when it really is the right tool; the inventors of C
>>> understood that.  From the Plan 9 `fortunes` file: "If you want
>>> to go somewhere, goto is the best way to get there. K Thompson"
>>
>> Certainly there are situations where people feel the most clear, simple,
>> reliable and efficient way to handle a particular bit of code is with a
>> "goto".  Fair enough.  Personally, I have almost never felt I am in that
>> situation.  I can think of perhaps four reasons why I might have fewer
>> goto's than some other people :
>>
>> 1. I stick to optimising compilers in almost all cases - some people may
>> use goto rather than an extra bool flag or too, for efficiency purposes.
>>   I am in the happy position of letting the compiler generate the goto's.
>>
>> 2. I almost never use dynamic memory, and thus don't have much use for a
>> typical "goto error" idiom for handling failed malloc.
>>
>> 3. My code is typically not meant to be portable, so I can use things
>> like gcc's "cleanup" attribute that can replace the need of "goto error"
>> or other handling when breaking out of inner loops.
>>
>> 4. With C99 "inline" and modern tools that do inlining and other
>> inter-procedural optimisations, there is often less benefit in nested
>> loops that might need a multi-level break - you can split the code into
>> separate functions and use "return" to break out of the middle of loops.
>>
>> So I don't suggest that nobody has need of "goto", or that all "gotos"
>> are bad - merely that I very rarely have use of them myself.
> 
> I'm with you on almost all of these, though I find the code that
> has to check a boolean or other flag in an outer loop to be hard
> to read compared to the `goto` alternative often enough that I
> avoid it if I can.  Of course, that's subjective.  And I might
> point out that there are other categories of cleanup one might
> want to do, aside from just freeing memory (in the embedded
> space, perhaps clearing a flag or setting register state in some
> device to reset it...).

Agreed.

> 
> I particularly agree with the use of a static inline to avoid
> some `goto`s.  When the `goto fail` bug was announced, as an
> exercise, I rewrote Apple's code to demonstrate how one might
> eliminate the problematic pattern entirely:
> 

(The mixture of tabs and spaces in your post resulted in a bit messed up 
indentation in the quotation in my reply.  I've tried to fix it up to 
match the original indentation, but be warned it might look different 
when you view it or re-quote it.)

> The original was something like:
> 
>      int
>      thing_that_can_fail(void)
>      {
>         int err = FAILURE;
>         void *p = malloc(...);
>         if (p == NULL)
>             goto fail;
>         void *q = whatever(...);
>         if (q == NULL)
>             goto fail;
>         err = something(p, q);
>         if (err != 0)
>             goto fail;
>         err = otherthing(p, q);
>         if (err != 0)
>             goto fail;
>             goto fail;
>         err = thirdthing(p, q);
>         if (err != 0)
>             goto fail;
>         return 0;
>     fail:
>         if (q != NULL)
>             dispose_of_q(q);
>         free(p);
>         return err;
>      }
> 
> But using a small `static` inline function, we can rewrite this
> as two functions that separate resource allocation and whatever
> else from other fallable logic:
> 
>      static inline int
>      do_thing_that_can_fail(void *p, void *q)
>      {
>          int err = something(p, q);
>          if (err != 0)
>              return err;
>          err = otherthing(p, q);
>          if (err != 0)
>              return err;
>          return thirdthing(p, q);
>      }
> 
>      int
>      thing_that_can_fail(void)
>      {
>          void *p = malloc(...);
> 	   if (p == NULL)
> 	       return FAILURE;
> 	   void *q = whatever(...);
> 	   if (q == NULL) {
>              free(p);
>              return FAILURE;
>          }
>          int ret = do_thing_that_can_fail(p, q);
>          dispose_of_q(q);
>          free(p);
>          return ret;
>      }
> 
> The response (this was amongst a bunch of developers are my last
> company) was, "yeah, but you can't _always_ do that..." and that
> may be true; but you _often_ can.  

Exactly.  Some people worry do much about when you can't do something, 
or what might go wrong if things had been different.  Use the best 
technique you can for the code at hand, and if you can't use that 
technique in one place, use something else in that one place.

> Regardless, it does not
> automatically follow that `goto` is the best option for dealing
> with this kind of failure.  The Plan 9 kernel, for example, used
> something equivalent to setjmp/longjmp and a stack of jump
> buffers to provide a primitive exception handling mechanism in
> that system's decidedly non-ISO dialect of C.
> 

There are other ways to avoid or catch such errors, without changing the 
structure or the use of "goto".  One is to use static error checking.  I 
don't know the age of this code, but from gcc 6 onwards "-Wall" will 
catch the "misleading indentation" of the double "goto fail".  (gcc also 
spots that the first "goto fail" skips the initialisation of "q", so it 
is tested and possibly disposed-of when uninitialised.  But that might 
be an artifact of your paraphrasing of the original code.)  Other static 
error checkers would also no doubt be able to spot the bug.

There is also the question of brace style.  That is something that 
people have lots of different opinions on, but there's no doubt that if 
the author had used a style that required the use of braces even for 
single-statement blocks, such as the so-called "One True Brace Style", 
then the error could not have occurred.

Personally, I allow a single short statement on the same line as the 
"if".  But if the statement is long, or I think the code is clearer 
having it on a separate line, or if there is an "else" clause, I have it 
in braces :

	if (!p) goto fail;

	if (!p) {
		goto fail;
	}

For me, this keeps everything simple, consistent, difficult to misread, 
fits well with version control and other line-by-line comparisons, and 
has a good balance between compactness and verbosity.

Other people, of course, have other style preferences, with different 
pros and cons.  OTBS, or my variation, would have made the error in this 
code impossible - but it would not have hindered other kinds of bugs.

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


#399244

Fromcross@spitfire.i.gajendra.net (Dan Cross)
Date2026-05-21 12:18 +0000
Message-ID<10umt5o$12$1@reader1.panix.com>
In reply to#399240
In article <10umdsa$hnml$1@dont-email.me>,
David Brown  <david.brown@hesbynett.no> wrote:
>On 20/05/2026 20:17, Dan Cross wrote:
>> [snip]
>> I particularly agree with the use of a static inline to avoid
>> some `goto`s.  When the `goto fail` bug was announced, as an
>> exercise, I rewrote Apple's code to demonstrate how one might
>> eliminate the problematic pattern entirely:
>> 
>
>(The mixture of tabs and spaces in your post resulted in a bit messed up 
>indentation in the quotation in my reply.  I've tried to fix it up to 
>match the original indentation, but be warned it might look different 
>when you view it or re-quote it.)

Apologies for that; I suspect that was my editor trying to be
"helpful": I used spaces in the example, but usually use tabs;
I probably should have just stuck with the latter for
consistency.

>> [snip code examples]
>> 
>> The response (this was amongst a bunch of developers are my last
>> company) was, "yeah, but you can't _always_ do that..." and that
>> may be true; but you _often_ can.  
>
>Exactly.  Some people worry do much about when you can't do something, 
>or what might go wrong if things had been different.  Use the best 
>technique you can for the code at hand, and if you can't use that 
>technique in one place, use something else in that one place.

Yes.

>> Regardless, it does not
>> automatically follow that `goto` is the best option for dealing
>> with this kind of failure.  The Plan 9 kernel, for example, used
>> something equivalent to setjmp/longjmp and a stack of jump
>> buffers to provide a primitive exception handling mechanism in
>> that system's decidedly non-ISO dialect of C.
>
>There are other ways to avoid or catch such errors, without changing the 
>structure or the use of "goto".  One is to use static error checking.  I 
>don't know the age of this code, but from gcc 6 onwards "-Wall" will 
>catch the "misleading indentation" of the double "goto fail".  (gcc also 
>spots that the first "goto fail" skips the initialisation of "q", so it 
>is tested and possibly disposed-of when uninitialised.  But that might 
>be an artifact of your paraphrasing of the original code.)  Other static 
>error checkers would also no doubt be able to spot the bug.

(The uninitialized `q` error was my mistake; this was only meant
to be illustrative, not actual working code!)

>There is also the question of brace style.  That is something that 
>people have lots of different opinions on, but there's no doubt that if 
>the author had used a style that required the use of braces even for 
>single-statement blocks, such as the so-called "One True Brace Style", 
>then the error could not have occurred.
>
>Personally, I allow a single short statement on the same line as the 
>"if".  But if the statement is long, or I think the code is clearer 
>having it on a separate line, or if there is an "else" clause, I have it 
>in braces :
>
>	if (!p) goto fail;
>
>	if (!p) {
>		goto fail;
>	}
>
>For me, this keeps everything simple, consistent, difficult to misread, 
>fits well with version control and other line-by-line comparisons, and 
>has a good balance between compactness and verbosity.
>
>Other people, of course, have other style preferences, with different 
>pros and cons.  OTBS, or my variation, would have made the error in this 
>code impossible - but it would not have hindered other kinds of bugs.

This writeup of the original bug is pretty good:
https://dwheeler.com/essays/apple-goto-fail.html

He also recommends several of the techniques you do.

In this particular case, the bug _should_ have been caught.
Some combination of rigorous testing, static analysis, and
manual review ought to have prevented it; that the bug made it
into production software anyway is a software engineering
failure.

I think one can level some reasonable criticism at the language,
however.  The `goto error;` idiom is used in C because there are
few alternatives for cleanup handling on failure.  Modulo what
we discussed before, that code can _often_ be restructured to
avoid it, but sometimes it can't, and frequently it just isn't.

In contrast, newer languages give you more expressive power in
this regard: Go has the `defer` keyword to register a closure
that runs when the enclosing function returns:

```go
	f, err := os.Open(...)
	if err != nil {
		return err
	}
	defer f.Close()
	...
```

The list of deferred closures will be run whenever the function
returns, no matter what path it takes.  You can't accidentally
omit the close.

Similarly, the RAII idiom prevalent in C++ and Rust uses object
destructors that are automatically run when something goes out
of scope to do the cleanup.  C++ pairs that with
exceptions (arguably worse than goto) while Rust represents
errors with sum types and a little bit of syntactic sugar with
the `?` operator.  In either case, the descriptors run and do
the cleanup, regardless of whether the return was an error path
or a success path.

Other languages feature "linear types", instances of which must
be used exactly once: failure to cleanup on an error path is a
compile time error.  This means that you can't forget to
deallocate memory, close a file, or unlock a mutex, for example,
but I don't know that it directly addresses the issue where you
just skip over the actual thing the program is supposed to do.
Still, with more expressive type systems, it is likely one can
much more easily structure the program so that the type of logic
that lead to this failure is unnecessary.

I understand that someone has written a paper proposing adding
`defer` to C; that would obviate many of these problems.

	- Dan C.

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


#399248

FromDavid Brown <david.brown@hesbynett.no>
Date2026-05-21 15:16 +0200
Message-ID<10un0j7$obiv$2@dont-email.me>
In reply to#399244
On 21/05/2026 14:18, Dan Cross wrote:
> In article <10umdsa$hnml$1@dont-email.me>,
> David Brown  <david.brown@hesbynett.no> wrote:
>> On 20/05/2026 20:17, Dan Cross wrote:
>>> [snip]
>>> I particularly agree with the use of a static inline to avoid
>>> some `goto`s.  When the `goto fail` bug was announced, as an
>>> exercise, I rewrote Apple's code to demonstrate how one might
>>> eliminate the problematic pattern entirely:
>>>
>>
>> (The mixture of tabs and spaces in your post resulted in a bit messed up
>> indentation in the quotation in my reply.  I've tried to fix it up to
>> match the original indentation, but be warned it might look different
>> when you view it or re-quote it.)
> 
> Apologies for that; I suspect that was my editor trying to be
> "helpful": I used spaces in the example, but usually use tabs;
> I probably should have just stuck with the latter for
> consistency.
> 

No problem - I just wanted to point it out in case my own posts looked 
wrong.

<snip for brevity>

> 
> This writeup of the original bug is pretty good:
> https://dwheeler.com/essays/apple-goto-fail.html
> 

I believe I read that at the time of the event.  It's good to work 
through such critical errors to see how to avoid them in the future.

> He also recommends several of the techniques you do.
> 
> In this particular case, the bug _should_ have been caught.
> Some combination of rigorous testing, static analysis, and
> manual review ought to have prevented it; that the bug made it
> into production software anyway is a software engineering
> failure.
> 
> I think one can level some reasonable criticism at the language,
> however.  The `goto error;` idiom is used in C because there are
> few alternatives for cleanup handling on failure.  Modulo what
> we discussed before, that code can _often_ be restructured to
> avoid it, but sometimes it can't, and frequently it just isn't.
> 

I think "isn't" is more common than "can't".  But I also don't think the 
"goto error" idiom is necessarily bad in itself - it's just that it is 
often used badly.  A typical indication of poor usage is when a function 
is getting very long, and there are multiple "error" labels.

However, the problem with this code was not the "goto error" idiom, or 
the "goto" itself - the problem was the mismatch between indentation and 
the statement under control of the "if".  It would have been equally bad 
if it had been "return" rather than "goto", or if gcc cleanup attributes 
had been used to handle cleanup, or if some kind of "defer" mechanism 
had been used (as supported by some programming languages, and proposed 
for a future C version).

These various cleanup mechanisms can definitely be better than "goto 
error", but they would not have prevented this error.  (A programming 
language that requires braces for statements controlled by "if", on the 
other hand, /would/ have prevented the error.)

> In contrast, newer languages give you more expressive power in
> this regard: Go has the `defer` keyword to register a closure
> that runs when the enclosing function returns:
> 
> ```go
> 	f, err := os.Open(...)
> 	if err != nil {
> 		return err
> 	}
> 	defer f.Close()
> 	...
> ```
> 
> The list of deferred closures will be run whenever the function
> returns, no matter what path it takes.  You can't accidentally
> omit the close.
> 
> Similarly, the RAII idiom prevalent in C++ and Rust uses object
> destructors that are automatically run when something goes out
> of scope to do the cleanup.  C++ pairs that with
> exceptions (arguably worse than goto) while Rust represents
> errors with sum types and a little bit of syntactic sugar with
> the `?` operator.  In either case, the descriptors run and do
> the cleanup, regardless of whether the return was an error path
> or a success path.

These are all nice ways of handling cleanup.

> 
> Other languages feature "linear types", instances of which must
> be used exactly once: failure to cleanup on an error path is a
> compile time error.  This means that you can't forget to
> deallocate memory, close a file, or unlock a mutex, for example,
> but I don't know that it directly addresses the issue where you
> just skip over the actual thing the program is supposed to do.
> Still, with more expressive type systems, it is likely one can
> much more easily structure the program so that the type of logic
> that lead to this failure is unnecessary.
> 

There is definitely potential for a language's type system to make it 
harder to make some kinds of mistakes.  But there is a risk in making 
the language too restrictive - people end up writing horrible code to 
work around restrictions, or use "unsafe" code too much.

I did some work, eons ago, in a language called XC that was specifically 
for XMOS microcontrollers.  The language and tools had a feature that 
made data races impossible by not allowing competing access to shared 
variables from different threads.  Since threads were part of the 
hardware, and the tools analysed the code flow through threads, this 
could all be enforced at build time - data had to be passed in messages, 
not shared memory.  But for some things that involved large buffers, 
that was hopelessly inefficient - and these devices were regularly used 
with USB, audio, and similar things that needed large and predictable 
buffers.  So code - even library and example code from the manufacturer 
- was full of inline assembly to work around the "smart-arse" language 
and tools.

> I understand that someone has written a paper proposing adding
> `defer` to C; that would obviate many of these problems.
> 
> 	- Dan C.
> 

Yes.  Jens Gustedt - one of the few members of the C standards committee 
who is vocal and public about pushing new ideas into C.  (Of course not 
everyone will agree with the ideas he comes with.)

<https://gustedt.wordpress.com/2026/02/15/defer-available-in-gcc-and-clang/>


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


#399313

Fromcross@spitfire.i.gajendra.net (Dan Cross)
Date2026-05-22 14:44 +0000
Message-ID<10upq57$ohg$1@reader1.panix.com>
In reply to#399248
In article <10un0j7$obiv$2@dont-email.me>,
David Brown  <david.brown@hesbynett.no> wrote:
>On 21/05/2026 14:18, Dan Cross wrote:
>> In article <10umdsa$hnml$1@dont-email.me>,
>> David Brown  <david.brown@hesbynett.no> wrote:
>> [snip]
>> I think one can level some reasonable criticism at the language,
>> however.  The `goto error;` idiom is used in C because there are
>> few alternatives for cleanup handling on failure.  Modulo what
>> we discussed before, that code can _often_ be restructured to
>> avoid it, but sometimes it can't, and frequently it just isn't.
>
>I think "isn't" is more common than "can't".

Yes, that's the distinction I tried to draw.

>But I also don't think the 
>"goto error" idiom is necessarily bad in itself - it's just that it is 
>often used badly.  A typical indication of poor usage is when a function 
>is getting very long, and there are multiple "error" labels.
>
>However, the problem with this code was not the "goto error" idiom, or 
>the "goto" itself - the problem was the mismatch between indentation and 
>the statement under control of the "if".  It would have been equally bad 
>if it had been "return" rather than "goto", or if gcc cleanup attributes 
>had been used to handle cleanup, or if some kind of "defer" mechanism 
>had been used (as supported by some programming languages, and proposed 
>for a future C version).
>
>These various cleanup mechanisms can definitely be better than "goto 
>error", but they would not have prevented this error.  (A programming 
>language that requires braces for statements controlled by "if", on the 
>other hand, /would/ have prevented the error.)

Yes, the immediate cause of the error was the repeated `goto`;
whether the misleading indentation was observed by the
programmer or not I couldn't say, however.  I have no way of
knowing, but my sense at the time was that this was an example
of copy-paste gone wrong.  Wheeler suggested it might be due to
removal as well; that's plausable.

I do agree that a language where the grammar forced braces (or
the equivalent) around conditionals would have prevented this,
or at least made it much more obvious.  Notably, both Rust and
Go do that.  Both also have automated formatters that are used
as a matter of course, which would have made the error easier to
spot; compare to the myriad different individual styles of C and
C++, and paucity of effective formatters.

Another method, one that I don't particularly care for, would
have been to nest the conditionals on success; this gets ugly
because code tends to move towards the right, and deeply nested
control structures can be terribly confusing.

However, Ken Thompson used to commit this grave sin, which sort
of ameliorates the problem:

	if ((err = thing()) == SUCCESS)
	if ((err = other()) == SUCCESS)
	if ((err = third()) == SUCCESS)
		dosomething();
	return err;

One could, of course, string those conditional together into a
single `if` using `&&`, but Ken thought this was cleaner.

>> [snip]
>> Other languages feature "linear types", instances of which must
>> be used exactly once: failure to cleanup on an error path is a
>> compile time error.  This means that you can't forget to
>> deallocate memory, close a file, or unlock a mutex, for example,
>> but I don't know that it directly addresses the issue where you
>> just skip over the actual thing the program is supposed to do.
>> Still, with more expressive type systems, it is likely one can
>> much more easily structure the program so that the type of logic
>> that lead to this failure is unnecessary.
>
>There is definitely potential for a language's type system to make it 
>harder to make some kinds of mistakes.  But there is a risk in making 
>the language too restrictive - people end up writing horrible code to 
>work around restrictions, or use "unsafe" code too much.

Interesting.  I've found it to be somewhat the opposite; using a
richer type system has lead to code that is easier to understand
and reason about, and less buggy: type-oriented programming can
make entire categories of errors *unrepresentable*, so it's not
just _harder_ to make certain kinds of mistakes, but
_impossible_.  The existance of an object of some type can be
thought of as an existence proof that the invariants the type
represents hold.

And Alexis King wrote the great, "Parse, Don't Validate" essay
some years ago where she talks about "Type-Driven Development":
https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/

More recently, Yaron Minsky gave a talk and discussed this in an
OCaml context (https://www.youtube.com/watch?v=rUYP4C29yCw; the
most relevant bits start at about 6:35.  The talk is about AI
and constraining agents, but the discussion around types is more
general).

I wrote the production OS loader for Oxide compute sleds using
this technique in the virtual memory system (and other places):
the loader uses multiple page sizes, and the rule is that, when
mapping a region of memory, it uses the largest page size that
it can, given size and alignment constraints.  But I use the
type system to make it impossible to, say, map a 2MiB "large"
physical page frame to a non-2MiB aligned virtual boundary.

>I did some work, eons ago, in a language called XC that was specifically 
>for XMOS microcontrollers.  The language and tools had a feature that 
>made data races impossible by not allowing competing access to shared 
>variables from different threads.  Since threads were part of the 
>hardware, and the tools analysed the code flow through threads, this 
>could all be enforced at build time - data had to be passed in messages, 
>not shared memory.  But for some things that involved large buffers, 
>that was hopelessly inefficient - and these devices were regularly used 
>with USB, audio, and similar things that needed large and predictable 
>buffers.  So code - even library and example code from the manufacturer 
>- was full of inline assembly to work around the "smart-arse" language 
>and tools.

Hmm.  This reads less like an indictment of the idea of stronger
typing, but rather a failure to provide adequate abstractions in
the type system.

I'm going to mention Rust again; apologies.  When confined to
the safe subset, it _also_ has data race freedom.  The rules
that give this property are:

1. Every object has exactly one owner, and assignments of
   non-trivial types change ownership (they are logically a
   "move");
2. References to an object may be "borrowed" from the owner,
   and mutable references (that is, references that may be used
   to write to the object) are distinct from immutable
   references (that is, references that may only be used to read
   from an object);
3. Mutable and immutable references are temporally mutually
   exclusive: a mutable reference may be borrowed from an object
   iff that is the only live reference to that object at the
   time: that is, it is not permitted to borrow a mut ref to an
   object if either another mut ref or any immutable refs to it
   are live; any number of immutable references may be taken to
   an object concurrently.

If all of these rules are obeyed (and in safe rust, they're
verified at compile time by the borrow checker) then you cannot
have data races.

At first glance it appears that it must suffer from the same
drawbacks as `XC`, which you mentioned above.  Except that the
language does provide controlled ways to share data
concurrently.

Using the _unsafe_ subset, there is one place where it is
permitted to have multiple, mutable references to an object: the
`UnsafeCell`.  This gives Rust interior mutability, which means
that you can build safe abstractions for data sharing, like
`Mutex` types that own the data they protect.

That last bit is important: since the `Mutex` owns whatever it
protects, it controls access to that thing: there's no going
behind the `Mutex`'s back and accessing something outside of
the lock.  Instead, the `lock` method returns a `MutexGuard`
object, which one might think of as a handle to the data,
allowing the user to manipulate it, but also having a drop
method (in Rust, that's basically a destructor) that
automatically unlocks the mutex run the guard is destroyed.

Anyway, the point is, both the rigor _and_ the expressiveness of
the type system let you do things like this, whereas you just
cannot in C.

>> I understand that someone has written a paper proposing adding
>> `defer` to C; that would obviate many of these problems.
>
>Yes.  Jens Gustedt - one of the few members of the C standards committee 
>who is vocal and public about pushing new ideas into C.  (Of course not 
>everyone will agree with the ideas he comes with.)
>
><https://gustedt.wordpress.com/2026/02/15/defer-available-in-gcc-and-clang/>

Ah, I didn't realize it was Jens.  Very cool.

	- Dan C.

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


#399315

FromDavid Brown <david.brown@hesbynett.no>
Date2026-05-22 17:12 +0200
Message-ID<10uprpn$1hfpm$1@dont-email.me>
In reply to#399313
On 22/05/2026 16:44, Dan Cross wrote:
> In article <10un0j7$obiv$2@dont-email.me>,
> David Brown  <david.brown@hesbynett.no> wrote:
>> On 21/05/2026 14:18, Dan Cross wrote:
>>> In article <10umdsa$hnml$1@dont-email.me>,
>>> David Brown  <david.brown@hesbynett.no> wrote:

>>> [snip]
>>> Other languages feature "linear types", instances of which must
>>> be used exactly once: failure to cleanup on an error path is a
>>> compile time error.  This means that you can't forget to
>>> deallocate memory, close a file, or unlock a mutex, for example,
>>> but I don't know that it directly addresses the issue where you
>>> just skip over the actual thing the program is supposed to do.
>>> Still, with more expressive type systems, it is likely one can
>>> much more easily structure the program so that the type of logic
>>> that lead to this failure is unnecessary.
>>
>> There is definitely potential for a language's type system to make it
>> harder to make some kinds of mistakes.  But there is a risk in making
>> the language too restrictive - people end up writing horrible code to
>> work around restrictions, or use "unsafe" code too much.
> 
> Interesting.  I've found it to be somewhat the opposite; using a
> richer type system has lead to code that is easier to understand
> and reason about, and less buggy: type-oriented programming can
> make entire categories of errors *unrepresentable*, so it's not
> just _harder_ to make certain kinds of mistakes, but
> _impossible_.  The existance of an object of some type can be
> thought of as an existence proof that the invariants the type
> represents hold.

In general, I agree - I prefer strongly typed languages, and it's always 
best if an error is identified by the code being uncompilable rather 
than waiting for run-time testing (or testing by evil hackers).  But if 
people want to do something with the language that is hard to achieve 
efficiently within the norms of the language, and there are escape 
hatches ("unsafe" code, inline assembly, calling external C functions, 
etc.) then people will use them.  People do sometimes write C code that 
knowingly depends on undefined behaviour, because it makes their results 
more efficient and "it worked when I tested it".

Type safety - like any kind of safety - can sometimes get in the way of 
"getting things done".  A balance always needs to be found to ensure 
that people can do what they need to do without breaking rules or using 
"escapes" more than absolutely necessary.  If people find that much of 
their Rust code is "unsafe", then most of the point of using Rust is 
lost.  (Of course this also means that different languages are suited to 
different tasks.)

> 
> And Alexis King wrote the great, "Parse, Don't Validate" essay
> some years ago where she talks about "Type-Driven Development":
> https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/
> 
> More recently, Yaron Minsky gave a talk and discussed this in an
> OCaml context (https://www.youtube.com/watch?v=rUYP4C29yCw; the
> most relevant bits start at about 6:35.  The talk is about AI
> and constraining agents, but the discussion around types is more
> general).
> 
> I wrote the production OS loader for Oxide compute sleds using
> this technique in the virtual memory system (and other places):
> the loader uses multiple page sizes, and the rule is that, when
> mapping a region of memory, it uses the largest page size that
> it can, given size and alignment constraints.  But I use the
> type system to make it impossible to, say, map a 2MiB "large"
> physical page frame to a non-2MiB aligned virtual boundary.
> 
>> I did some work, eons ago, in a language called XC that was specifically
>> for XMOS microcontrollers.  The language and tools had a feature that
>> made data races impossible by not allowing competing access to shared
>> variables from different threads.  Since threads were part of the
>> hardware, and the tools analysed the code flow through threads, this
>> could all be enforced at build time - data had to be passed in messages,
>> not shared memory.  But for some things that involved large buffers,
>> that was hopelessly inefficient - and these devices were regularly used
>> with USB, audio, and similar things that needed large and predictable
>> buffers.  So code - even library and example code from the manufacturer
>> - was full of inline assembly to work around the "smart-arse" language
>> and tools.
> 
> Hmm.  This reads less like an indictment of the idea of stronger
> typing, but rather a failure to provide adequate abstractions in
> the type system.

It is not an indication of problems with stronger typing, but it is an 
indication that the restrictions inherent in the language and tools made 
them somewhat unsuitable for a lot of use-cases that fitted the hardware 
well.  (Modern XMOS tools have changed significantly since those days, 
perhaps partly because of such issues.)

> 
> I'm going to mention Rust again; apologies.  When confined to
> the safe subset, it _also_ has data race freedom.  The rules
> that give this property are:
> 
> 1. Every object has exactly one owner, and assignments of
>     non-trivial types change ownership (they are logically a
>     "move");
> 2. References to an object may be "borrowed" from the owner,
>     and mutable references (that is, references that may be used
>     to write to the object) are distinct from immutable
>     references (that is, references that may only be used to read
>     from an object);
> 3. Mutable and immutable references are temporally mutually
>     exclusive: a mutable reference may be borrowed from an object
>     iff that is the only live reference to that object at the
>     time: that is, it is not permitted to borrow a mut ref to an
>     object if either another mut ref or any immutable refs to it
>     are live; any number of immutable references may be taken to
>     an object concurrently.
> 
> If all of these rules are obeyed (and in safe rust, they're
> verified at compile time by the borrow checker) then you cannot
> have data races.

That's all good, by the sound of it.  But if people find this gets in 
the way of efficiency - perhaps because they know that it is safe to 
hold two separate mutable references to an object for reasons the borrow 
checker can't see - the temptation to use "unsafe" or other workarounds 
comes quickly.

That does not mean that a language should not try to have such rules, 
and enforce them at compile time - far from it.  The aim should be that 
as much code as possible is correct, or at least immune to particular 
classes of bugs, checked by the compiler and tools.

> 
> At first glance it appears that it must suffer from the same
> drawbacks as `XC`, which you mentioned above.  Except that the
> language does provide controlled ways to share data
> concurrently.
> 
> Using the _unsafe_ subset, there is one place where it is
> permitted to have multiple, mutable references to an object: the
> `UnsafeCell`.  This gives Rust interior mutability, which means
> that you can build safe abstractions for data sharing, like
> `Mutex` types that own the data they protect.
> 

If "unsafe" gives enough, but is rarely needed in most code, then it 
sounds like a good balance.

> That last bit is important: since the `Mutex` owns whatever it
> protects, it controls access to that thing: there's no going
> behind the `Mutex`'s back and accessing something outside of
> the lock.  Instead, the `lock` method returns a `MutexGuard`
> object, which one might think of as a handle to the data,
> allowing the user to manipulate it, but also having a drop
> method (in Rust, that's basically a destructor) that
> automatically unlocks the mutex run the guard is destroyed.
> 
> Anyway, the point is, both the rigor _and_ the expressiveness of
> the type system let you do things like this, whereas you just
> cannot in C.
> 

Sure.

>>> I understand that someone has written a paper proposing adding
>>> `defer` to C; that would obviate many of these problems.
>>
>> Yes.  Jens Gustedt - one of the few members of the C standards committee
>> who is vocal and public about pushing new ideas into C.  (Of course not
>> everyone will agree with the ideas he comes with.)
>>
>> <https://gustedt.wordpress.com/2026/02/15/defer-available-in-gcc-and-clang/>
> 
> Ah, I didn't realize it was Jens.  Very cool.
> 
> 	- Dan C.
> 

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


#399403

Fromcross@spitfire.i.gajendra.net (Dan Cross)
Date2026-05-24 19:08 +0000
Message-ID<10uvic7$63b$1@reader1.panix.com>
In reply to#399315
In article <10uprpn$1hfpm$1@dont-email.me>,
David Brown  <david.brown@hesbynett.no> wrote:
>On 22/05/2026 16:44, Dan Cross wrote:
>> In article <10un0j7$obiv$2@dont-email.me>,
>> David Brown  <david.brown@hesbynett.no> wrote:
>>> [snip]
>>> There is definitely potential for a language's type system to make it
>>> harder to make some kinds of mistakes.  But there is a risk in making
>>> the language too restrictive - people end up writing horrible code to
>>> work around restrictions, or use "unsafe" code too much.
>> 
>> Interesting.  I've found it to be somewhat the opposite; using a
>> richer type system has lead to code that is easier to understand
>> and reason about, and less buggy: type-oriented programming can
>> make entire categories of errors *unrepresentable*, so it's not
>> just _harder_ to make certain kinds of mistakes, but
>> _impossible_.  The existance of an object of some type can be
>> thought of as an existence proof that the invariants the type
>> represents hold.
>
>In general, I agree - I prefer strongly typed languages, and it's always 
>best if an error is identified by the code being uncompilable rather 
>than waiting for run-time testing (or testing by evil hackers).  But if 
>people want to do something with the language that is hard to achieve 
>efficiently within the norms of the language, and there are escape 
>hatches ("unsafe" code, inline assembly, calling external C functions, 
>etc.) then people will use them.

Sure; that seems pretty clear, given extensive available
evidence.

>People do sometimes write C code that 
>knowingly depends on undefined behaviour, because it makes their results 
>more efficient and "it worked when I tested it".

Yes, or they force some knob on their compiler into the required
position to give them guaranteed results.  Linux does this, for
example; last time I worked in it, Google's massive (2BLOC) code
base similarly.

>Type safety - like any kind of safety - can sometimes get in the way of 
>"getting things done".  A balance always needs to be found to ensure 
>that people can do what they need to do without breaking rules or using 
>"escapes" more than absolutely necessary.  If people find that much of 
>their Rust code is "unsafe", then most of the point of using Rust is 
>lost.  (Of course this also means that different languages are suited to 
>different tasks.)

It _can_, but I wouldn't take it as a given that it _does_, and
what I'm trying to say is that contrary to often getting in the
way, it can be used effectively to make programs better and
safer, with no runtime downside.  Indeed, a well-typed program
can be faster than the alternative, since a) the compiler can
prove that some properties hold, and b) it can be more
aggressively optimized at a higher level.  An example here are
non-nullable references; there's no need to check whether they
are NULL or not before indirecting through them, since by
definition they cannot be NULL.

>> And Alexis King wrote the great, "Parse, Don't Validate" essay
>> some years ago where she talks about "Type-Driven Development":
>> https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/
>> 
>> More recently, Yaron Minsky gave a talk and discussed this in an
>> OCaml context (https://www.youtube.com/watch?v=rUYP4C29yCw; the
>> most relevant bits start at about 6:35.  The talk is about AI
>> and constraining agents, but the discussion around types is more
>> general).
>> 
>> I wrote the production OS loader for Oxide compute sleds using
>> this technique in the virtual memory system (and other places):
>> the loader uses multiple page sizes, and the rule is that, when
>> mapping a region of memory, it uses the largest page size that
>> it can, given size and alignment constraints.  But I use the
>> type system to make it impossible to, say, map a 2MiB "large"
>> physical page frame to a non-2MiB aligned virtual boundary.
>> 
>>> I did some work, eons ago, in a language called XC that was specifically
>>> for XMOS microcontrollers.  The language and tools had a feature that
>>> made data races impossible by not allowing competing access to shared
>>> variables from different threads.  Since threads were part of the
>>> hardware, and the tools analysed the code flow through threads, this
>>> could all be enforced at build time - data had to be passed in messages,
>>> not shared memory.  But for some things that involved large buffers,
>>> that was hopelessly inefficient - and these devices were regularly used
>>> with USB, audio, and similar things that needed large and predictable
>>> buffers.  So code - even library and example code from the manufacturer
>>> - was full of inline assembly to work around the "smart-arse" language
>>> and tools.
>> 
>> Hmm.  This reads less like an indictment of the idea of stronger
>> typing, but rather a failure to provide adequate abstractions in
>> the type system.
>
>It is not an indication of problems with stronger typing, but it is an 
>indication that the restrictions inherent in the language and tools made 
>them somewhat unsuitable for a lot of use-cases that fitted the hardware 
>well.  (Modern XMOS tools have changed significantly since those days, 
>perhaps partly because of such issues.)

Sure, but that's a failure of that system to provide good
abstractions: the system was not rich enough to provide the
functionality you needed or wanted.

I think the central tension here is that the idea of a strong
type system that is also semantically rich is being conflated
with one that's highly restrictive.  What I'm suggesting is that
the opposite is true.

>> I'm going to mention Rust again; apologies.  When confined to
>> the safe subset, it _also_ has data race freedom.  The rules
>> that give this property are:
>> 
>> 1. Every object has exactly one owner, and assignments of
>>     non-trivial types change ownership (they are logically a
k>>     "move");
>> 2. References to an object may be "borrowed" from the owner,
>>     and mutable references (that is, references that may be used
>>     to write to the object) are distinct from immutable
>>     references (that is, references that may only be used to read
>>     from an object);
>> 3. Mutable and immutable references are temporally mutually
>>     exclusive: a mutable reference may be borrowed from an object
>>     iff that is the only live reference to that object at the
>>     time: that is, it is not permitted to borrow a mut ref to an
>>     object if either another mut ref or any immutable refs to it
>>     are live; any number of immutable references may be taken to
>>     an object concurrently.
>> 
>> If all of these rules are obeyed (and in safe rust, they're
>> verified at compile time by the borrow checker) then you cannot
>> have data races.
>
>That's all good, by the sound of it.  But if people find this gets in 
>the way of efficiency - perhaps because they know that it is safe to 
>hold two separate mutable references to an object for reasons the borrow 
>checker can't see - the temptation to use "unsafe" or other workarounds 
>comes quickly.

Not really.  The rule is that borrowing a mutable reference to
some object is mutually exclusive with borrowing any other kind
of reference to that same object at the same time.  `unsafe`
doesn't change that rules, or let the programmer off the hook
for violating it: `unsafe` code isn't allowed to mix mut ref
with other references any more than _safe_ code.  All `unsafe`
means is that the burden of upholding the rules of the language
falls to the programmer, without compiler assistence, because
the programmer knows something that the compiler does not (and
probably cannot) for some reason.

However, if it really _is_ the case that multiple simultaneous
writes are ok, the ability to create new types and assign them
semantics and behavior menas that a programmer can build a _new_
abstraction that lets them do something similar.  Atomics are
an interesting case in point: one can store to them using a
non-mutable reference: while this seems counter-intuitive at
first, it sort of makes sense for the same reason that a `Mutex`
is accessed via an immutable reference: one cannot observe an
atomic in an intermediate state due to an update, and `load` and
`store` are explicit operations (in practice, the compiler
lowers those to single load/store operations and whatever
barriers are appropriate for the target architecture).  

A hardware device modeling a framebuffer might be another case;
those are output-only devices, and there's no reason that two
threads cannot write to different parts of the buffer at the
same time, but given a suitable interface, the interface doesn't
need to expose unsafety.  And if you've got a rich type system,
you have the rules to build that interface.

>That does not mean that a language should not try to have such rules, 
>and enforce them at compile time - far from it.  The aim should be that 
>as much code as possible is correct, or at least immune to particular 
>classes of bugs, checked by the compiler and tools.

I think you're saying something different than what I'm saying;
my point is that the safe interface shouldn't be seen as a
burden and, if well-executed, it shouldn't add a runtime tax in
terms of reduced performance.  You seem to be taking it as a
given that the rules of the language will make both of those
things true, however.

>> At first glance it appears that it must suffer from the same
>> drawbacks as `XC`, which you mentioned above.  Except that the
>> language does provide controlled ways to share data
>> concurrently.
>> 
>> Using the _unsafe_ subset, there is one place where it is
>> permitted to have multiple, mutable references to an object: the
>> `UnsafeCell`.  This gives Rust interior mutability, which means
>> that you can build safe abstractions for data sharing, like
>> `Mutex` types that own the data they protect.
>
>If "unsafe" gives enough, but is rarely needed in most code, then it 
>sounds like a good balance.

Yes.  And moreover, one can hide that unsafety behind a safe
interface.

	- Dan C.

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


#399419

FromDavid Brown <david.brown@hesbynett.no>
Date2026-05-25 12:16 +0200
Message-ID<10v17h4$18mp3$1@dont-email.me>
In reply to#399403
On 24/05/2026 21:08, Dan Cross wrote:
> In article <10uprpn$1hfpm$1@dont-email.me>,
> David Brown  <david.brown@hesbynett.no> wrote:
>> On 22/05/2026 16:44, Dan Cross wrote:
>>> In article <10un0j7$obiv$2@dont-email.me>,
>>> David Brown  <david.brown@hesbynett.no> wrote:
>>>> [snip]
>>>> There is definitely potential for a language's type system to make it
>>>> harder to make some kinds of mistakes.  But there is a risk in making
>>>> the language too restrictive - people end up writing horrible code to
>>>> work around restrictions, or use "unsafe" code too much.
>>>
>>> Interesting.  I've found it to be somewhat the opposite; using a
>>> richer type system has lead to code that is easier to understand
>>> and reason about, and less buggy: type-oriented programming can
>>> make entire categories of errors *unrepresentable*, so it's not
>>> just _harder_ to make certain kinds of mistakes, but
>>> _impossible_.  The existance of an object of some type can be
>>> thought of as an existence proof that the invariants the type
>>> represents hold.
>>
>> In general, I agree - I prefer strongly typed languages, and it's always
>> best if an error is identified by the code being uncompilable rather
>> than waiting for run-time testing (or testing by evil hackers).  But if
>> people want to do something with the language that is hard to achieve
>> efficiently within the norms of the language, and there are escape
>> hatches ("unsafe" code, inline assembly, calling external C functions,
>> etc.) then people will use them.
> 
> Sure; that seems pretty clear, given extensive available
> evidence.
> 
>> People do sometimes write C code that
>> knowingly depends on undefined behaviour, because it makes their results
>> more efficient and "it worked when I tested it".
> 
> Yes, or they force some knob on their compiler into the required
> position to give them guaranteed results.  Linux does this, for
> example; last time I worked in it, Google's massive (2BLOC) code
> base similarly.
> 

What you then get is code that is UB in C, but not UB in 
C-with-no-strict-aliasing, or whatever "augmented" language you pick. 
(I have a strict policy of putting any such knobs in "GCC optimize" 
pragmas, so that the code correctness does not depend on the flags 
picked in a makefile.  Of course such code remains equally limited in 
its portability.)

>> Type safety - like any kind of safety - can sometimes get in the way of
>> "getting things done".  A balance always needs to be found to ensure
>> that people can do what they need to do without breaking rules or using
>> "escapes" more than absolutely necessary.  If people find that much of
>> their Rust code is "unsafe", then most of the point of using Rust is
>> lost.  (Of course this also means that different languages are suited to
>> different tasks.)
> 
> It _can_, but I wouldn't take it as a given that it _does_, and
> what I'm trying to say is that contrary to often getting in the
> way, it can be used effectively to make programs better and
> safer, with no runtime downside.  Indeed, a well-typed program
> can be faster than the alternative, since a) the compiler can
> prove that some properties hold, and b) it can be more
> aggressively optimized at a higher level.  An example here are
> non-nullable references; there's no need to check whether they
> are NULL or not before indirecting through them, since by
> definition they cannot be NULL.
> 

I fully agree.


>>>
>>> Hmm.  This reads less like an indictment of the idea of stronger
>>> typing, but rather a failure to provide adequate abstractions in
>>> the type system.
>>
>> It is not an indication of problems with stronger typing, but it is an
>> indication that the restrictions inherent in the language and tools made
>> them somewhat unsuitable for a lot of use-cases that fitted the hardware
>> well.  (Modern XMOS tools have changed significantly since those days,
>> perhaps partly because of such issues.)
> 
> Sure, but that's a failure of that system to provide good
> abstractions: the system was not rich enough to provide the
> functionality you needed or wanted.
> 
> I think the central tension here is that the idea of a strong
> type system that is also semantically rich is being conflated
> with one that's highly restrictive.  What I'm suggesting is that
> the opposite is true.

To be clear - the restrictions here were not part of the type system. 
The XC language did have some differences in typing from C, if I 
remember the details correctly - rather than C pointers it had 
references which could not be null.  And that's fine.

The restrictions were enforced by whole-program analysis.  I think (and 
you are the Rust expert here, not me) that the Rust borrow checker is 
similar.  The rules of the language specify aspects of what can and 
cannot be done with access to data, and these are enforced at a higher 
level than the main compilation.  They are language rules, but not part 
of the type system.

> 
>>> I'm going to mention Rust again; apologies.  When confined to
>>> the safe subset, it _also_ has data race freedom.  The rules
>>> that give this property are:
>>>
>>> 1. Every object has exactly one owner, and assignments of
>>>      non-trivial types change ownership (they are logically a
> k>>     "move");
>>> 2. References to an object may be "borrowed" from the owner,
>>>      and mutable references (that is, references that may be used
>>>      to write to the object) are distinct from immutable
>>>      references (that is, references that may only be used to read
>>>      from an object);
>>> 3. Mutable and immutable references are temporally mutually
>>>      exclusive: a mutable reference may be borrowed from an object
>>>      iff that is the only live reference to that object at the
>>>      time: that is, it is not permitted to borrow a mut ref to an
>>>      object if either another mut ref or any immutable refs to it
>>>      are live; any number of immutable references may be taken to
>>>      an object concurrently.
>>>
>>> If all of these rules are obeyed (and in safe rust, they're
>>> verified at compile time by the borrow checker) then you cannot
>>> have data races.
>>
>> That's all good, by the sound of it.  But if people find this gets in
>> the way of efficiency - perhaps because they know that it is safe to
>> hold two separate mutable references to an object for reasons the borrow
>> checker can't see - the temptation to use "unsafe" or other workarounds
>> comes quickly.
> 
> Not really.  The rule is that borrowing a mutable reference to
> some object is mutually exclusive with borrowing any other kind
> of reference to that same object at the same time.  `unsafe`
> doesn't change that rules, or let the programmer off the hook
> for violating it: `unsafe` code isn't allowed to mix mut ref
> with other references any more than _safe_ code.  All `unsafe`
> means is that the burden of upholding the rules of the language
> falls to the programmer, without compiler assistence, because
> the programmer knows something that the compiler does not (and
> probably cannot) for some reason.

That is roughly what I was trying to express, although there is perhaps 
a grey area between "I am following the rules even though the tools 
can't see it" and "I am breaking the rules but I know it is safe to do 
so here without compromising the reason for those rules".

In C (trying desperately to bring us back to c.l.c. :-) ), you might use 
casts to do something that looks wrong to the compiler, but which you 
know is safe and correct.

> 
> However, if it really _is_ the case that multiple simultaneous
> writes are ok, the ability to create new types and assign them
> semantics and behavior menas that a programmer can build a _new_
> abstraction that lets them do something similar.  Atomics are
> an interesting case in point: one can store to them using a
> non-mutable reference: while this seems counter-intuitive at
> first, it sort of makes sense for the same reason that a `Mutex`
> is accessed via an immutable reference: one cannot observe an
> atomic in an intermediate state due to an update, and `load` and
> `store` are explicit operations (in practice, the compiler
> lowers those to single load/store operations and whatever
> barriers are appropriate for the target architecture).

OK.  Though that is probably a level of detail that would be clearer to 
me if I read the Rust documentation first!

> 
> A hardware device modeling a framebuffer might be another case;
> those are output-only devices, and there's no reason that two
> threads cannot write to different parts of the buffer at the
> same time, but given a suitable interface, the interface doesn't
> need to expose unsafety.  And if you've got a rich type system,
> you have the rules to build that interface.

That is the kind of thing that was difficult in XC.  Perhaps it would be 
fair to say that its type system was not powerful enough to work 
conveniently with its data race and thread safety checking systems.

> 
>> That does not mean that a language should not try to have such rules,
>> and enforce them at compile time - far from it.  The aim should be that
>> as much code as possible is correct, or at least immune to particular
>> classes of bugs, checked by the compiler and tools.
> 
> I think you're saying something different than what I'm saying;
> my point is that the safe interface shouldn't be seen as a
> burden and, if well-executed, it shouldn't add a runtime tax in
> terms of reduced performance.  You seem to be taking it as a
> given that the rules of the language will make both of those
> things true, however.

I am saying that a safe interface /can/ sometimes be a burden - not that 
it has to be.

An interface defines what can be done, and also what cannot be done. 
It's power as an interface comes from both of these - letting you do 
useful things, and preventing you from doing harmful things.  Sometimes, 
however, there may be things you want to do that you know are useful and 
not harmful, but that the interface disallows.  If the language or 
interface is well designed, and a good fit for the tasks people want to 
do with the language, then such situations will be minimal.  But I think 
it is quite easy to fall into a trap when designing an interface where 
you exclude too many useful cases.  If that happens, then programmers 
have to use riskier or less efficient workarounds, or find alternative 
interfaces (or languages).

As a concrete example, I recently wanted to use a std::variant<> in my 
C++ code.  A std::variant<> is, approximately, a struct like :

	struct {
		enum { ... } type_tag;
		union { ... } contents;
	}

In C++, this is all type-safe - you don't have direct access to these 
fields, but instead they are kept consistent automatically so that 
objects of different types can be stored in the union and have their 
constructors and destructors called correctly.  But in my case, I wanted 
to access the fields independently - I wanted to fill the "contents" 
with data retrieved over a network, and set the "type_tag" according to 
other data in the network packet.  I knew this was safe (since no 
constructors or destructors were needed).  But there was no way to 
handle this within the interface.  My options included a risky, 
non-portable and difficult workaround (digging through the <variant> 
header and directly "hacking" the variant object using unsigned char* 
pointers), serious run-time inefficiencies (with extra copies of the 
data), or finding a different interface.  I opted for the last one, 
making my own simple variation of std::variant that gave me the access I 
needed.

This, of course, does not necessarily mean the interface of 
std::variant<> is bad.  If my needs were highly unusual, then a standard 
library does not need to support them.  But it is an example where the 
restrictions imposed by a safe, powerful interface limited how I could 
work with what is essentially the same kind of object.


> 
>>> At first glance it appears that it must suffer from the same
>>> drawbacks as `XC`, which you mentioned above.  Except that the
>>> language does provide controlled ways to share data
>>> concurrently.
>>>
>>> Using the _unsafe_ subset, there is one place where it is
>>> permitted to have multiple, mutable references to an object: the
>>> `UnsafeCell`.  This gives Rust interior mutability, which means
>>> that you can build safe abstractions for data sharing, like
>>> `Mutex` types that own the data they protect.
>>
>> If "unsafe" gives enough, but is rarely needed in most code, then it
>> sounds like a good balance.
> 
> Yes.  And moreover, one can hide that unsafety behind a safe
> interface.
> 

I do like that the unsafety is marked explicitly and clearly.

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


#399438

Fromcross@spitfire.i.gajendra.net (Dan Cross)
Date2026-05-26 14:09 +0000
Message-ID<10v49ic$3fq$1@reader1.panix.com>
In reply to#399419
In article <10v17h4$18mp3$1@dont-email.me>,
David Brown  <david.brown@hesbynett.no> wrote:
>On 24/05/2026 21:08, Dan Cross wrote:
>> In article <10uprpn$1hfpm$1@dont-email.me>,
>> David Brown  <david.brown@hesbynett.no> wrote:
>>> [snip]
>>> People do sometimes write C code that
>>> knowingly depends on undefined behaviour, because it makes their results
>>> more efficient and "it worked when I tested it".
>> 
>> Yes, or they force some knob on their compiler into the required
>> position to give them guaranteed results.  Linux does this, for
>> example; last time I worked in it, Google's massive (2BLOC) code
>> base similarly.
>
>What you then get is code that is UB in C, but not UB in 
>C-with-no-strict-aliasing, or whatever "augmented" language you pick. 

Yes.  An observation pointed out to me at my last gig, and that
I now point out occasionally myself, is that Linux (for example)
is not so much written in C but rather in Linux C, which is the
dialect of the language defined by the compilers they use and
the specific behaviors they force using flags, pragmas, etc, for
those compilers.  At any rate, it's certainly not strictly
conforming ISO C: is _any_ large program strictly conforming at
this point?  I suspect many projects strive for such, but few
actually attain it.

>(I have a strict policy of putting any such knobs in "GCC optimize" 
>pragmas, so that the code correctness does not depend on the flags 
>picked in a makefile.  Of course such code remains equally limited in 
>its portability.)

Good idea, though I like the idea of the compiler failing with a
usage error if an option is no longer available (or someone is
trying to build using an old compiler or what have you).

>>>> [snip]
>>>> Hmm.  This reads less like an indictment of the idea of stronger
>>>> typing, but rather a failure to provide adequate abstractions in
>>>> the type system.
>>>
>>> It is not an indication of problems with stronger typing, but it is an
>>> indication that the restrictions inherent in the language and tools made
>>> them somewhat unsuitable for a lot of use-cases that fitted the hardware
>>> well.  (Modern XMOS tools have changed significantly since those days,
>>> perhaps partly because of such issues.)
>> 
>> Sure, but that's a failure of that system to provide good
>> abstractions: the system was not rich enough to provide the
>> functionality you needed or wanted.
>> 
>> I think the central tension here is that the idea of a strong
>> type system that is also semantically rich is being conflated
>> with one that's highly restrictive.  What I'm suggesting is that
>> the opposite is true.
>
>To be clear - the restrictions here were not part of the type system. 
>The XC language did have some differences in typing from C, if I 
>remember the details correctly - rather than C pointers it had 
>references which could not be null.  And that's fine.
>
>The restrictions were enforced by whole-program analysis.  I think (and 
>you are the Rust expert here, not me) that the Rust borrow checker is 
>similar.  The rules of the language specify aspects of what can and 
>cannot be done with access to data, and these are enforced at a higher 
>level than the main compilation.  They are language rules, but not part 
>of the type system.

Sorry, let me be clear here: the _language_ is not expressive
enough to provide the kinds of abstractions that would be useful
for the types of applications the hardware seems well-suited
for.

But the original context was types; my point was that a richer
langauge can provide the building blocks so that one can build a
safe abstraction around those kinds of behaviors, even if one
uses `unsafe` in the implementation of those abstractions.

This was meant in response to your earlier statement, that e.g.
performance might cause one to want to reach for `unsafe` to
work _around_ the language; my point is that the language gives
you tools to work _with_ it.  That is, the initial desire to
reach for `unsafe` is _reduced_ by the ability to effectively
hide it.

Implicit in this is a distinction between building what one
might call infrastructure within one's program, and using that
infrastructure: the former might involve some controlled (and
hopefully limited) use of `unsafe`, while the latter ideally
does not.  I find this is the opposite of what many people
assume when coming from other language backgrounds, where the
desire is to push `unsafe` to the point of use; often this is
because in other languages, building up those abstractions
requires a lot of machinery with high runtime costs.

>> [snip]
>> Not really.  The rule is that borrowing a mutable reference to
>> some object is mutually exclusive with borrowing any other kind
>> of reference to that same object at the same time.  `unsafe`
>> doesn't change that rules, or let the programmer off the hook
>> for violating it: `unsafe` code isn't allowed to mix mut ref
>> with other references any more than _safe_ code.  All `unsafe`
>> means is that the burden of upholding the rules of the language
>> falls to the programmer, without compiler assistence, because
>> the programmer knows something that the compiler does not (and
>> probably cannot) for some reason.
>
>That is roughly what I was trying to express, although there is perhaps 
>a grey area between "I am following the rules even though the tools 
>can't see it" and "I am breaking the rules but I know it is safe to do 
>so here without compromising the reason for those rules".

That's what I'm saying; a program really _doesn't_ get to break
the rules and retain any guarantee of behavior, unsafe or not.
In that sense, writing `unsafe` Rust code is _harder_ than
writing C or another unsafe language.  There is no grey area:
either the programmer makes sure the program follows the rules,
or all bets are off.

>In C (trying desperately to bring us back to c.l.c. :-) ), you might use 
>casts to do something that looks wrong to the compiler, but which you 
>know is safe and correct.

That's qualitatively different, though.  If, say, I manually
validate that a pointer points to valid memory, and is properly
aligned, and so forth, then I can cast that pointer to some
type.  You can absolutely do that in Rust, too.  But if,
instead, you say, "I'm going to intentionally invoke UB here..."
then both languages will bite you.

>> However, if it really _is_ the case that multiple simultaneous
>> writes are ok, the ability to create new types and assign them
>> semantics and behavior menas that a programmer can build a _new_
>> abstraction that lets them do something similar.  Atomics are
>> an interesting case in point: one can store to them using a
>> non-mutable reference: while this seems counter-intuitive at
>> first, it sort of makes sense for the same reason that a `Mutex`
>> is accessed via an immutable reference: one cannot observe an
>> atomic in an intermediate state due to an update, and `load` and
>> `store` are explicit operations (in practice, the compiler
>> lowers those to single load/store operations and whatever
>> barriers are appropriate for the target architecture).
>
>OK.  Though that is probably a level of detail that would be clearer to 
>me if I read the Rust documentation first!
>
>> A hardware device modeling a framebuffer might be another case;
>> those are output-only devices, and there's no reason that two
>> threads cannot write to different parts of the buffer at the
>> same time, but given a suitable interface, the interface doesn't
>> need to expose unsafety.  And if you've got a rich type system,
>> you have the rules to build that interface.
>
>That is the kind of thing that was difficult in XC.  Perhaps it would be 
>fair to say that its type system was not powerful enough to work 
>conveniently with its data race and thread safety checking systems.

Yes.  It also doesn't give you any means to build an abstraction
that lets you do the thing you want to do.

>>> That does not mean that a language should not try to have such rules,
>>> and enforce them at compile time - far from it.  The aim should be that
>>> as much code as possible is correct, or at least immune to particular
>>> classes of bugs, checked by the compiler and tools.
>> 
>> I think you're saying something different than what I'm saying;
>> my point is that the safe interface shouldn't be seen as a
>> burden and, if well-executed, it shouldn't add a runtime tax in
>> terms of reduced performance.  You seem to be taking it as a
>> given that the rules of the language will make both of those
>> things true, however.
>
>I am saying that a safe interface /can/ sometimes be a burden - not that 
>it has to be.

Well yes, of course; I thought that was a given in the context
of this discussion.

>An interface defines what can be done, and also what cannot be done. 
>It's power as an interface comes from both of these - letting you do 
>useful things, and preventing you from doing harmful things.  Sometimes, 
>however, there may be things you want to do that you know are useful and 
>not harmful, but that the interface disallows.  If the language or 
>interface is well designed, and a good fit for the tasks people want to 
>do with the language, then such situations will be minimal.  But I think 
>it is quite easy to fall into a trap when designing an interface where 
>you exclude too many useful cases.  If that happens, then programmers 
>have to use riskier or less efficient workarounds, or find alternative 
>interfaces (or languages).

Yes.  And what I'm saying is that when working with a language
that allows you to create useful, robust, types, you can often
bridge the two worlds and build a new, useful abstraction.  C is
not a language where one can easily do that; you've got structs,
unions, and functions...and that's about it.  But you cannot
restrict the behavior of a struct in the way that King described
in the "Parse, Don't Validate" piece I linked earlier.

An instance of a struct is Not a proof that some property holds,
but it _may_ be in Rust or Haskell or OCaml, SML, etc.  I
suspect one cannot easily do that in C++, because it's not
managed and doesn't make ownership a first-class property,
though one can usefully write a number of classes and so forth
that give much the same effect, if not actual guarantees.
Interestingly (maybe?), I find Ada lacking in this area.

>As a concrete example, I recently wanted to use a std::variant<> in my 
>C++ code.  A std::variant<> is, approximately, a struct like :
>
>	struct {
>		enum { ... } type_tag;
>		union { ... } contents;
>	}
>
>In C++, this is all type-safe - you don't have direct access to these 
>fields, but instead they are kept consistent automatically so that 
>objects of different types can be stored in the union and have their 
>constructors and destructors called correctly.  But in my case, I wanted 
>to access the fields independently - I wanted to fill the "contents" 
>with data retrieved over a network, and set the "type_tag" according to 
>other data in the network packet.  I knew this was safe (since no 
>constructors or destructors were needed).  But there was no way to 
>handle this within the interface.  My options included a risky, 
>non-portable and difficult workaround (digging through the <variant> 
>header and directly "hacking" the variant object using unsigned char* 
>pointers), serious run-time inefficiencies (with extra copies of the 
>data), or finding a different interface.  I opted for the last one, 
>making my own simple variation of std::variant that gave me the access I 
>needed.
>
>This, of course, does not necessarily mean the interface of 
>std::variant<> is bad.  If my needs were highly unusual, then a standard 
>library does not need to support them.  But it is an example where the 
>restrictions imposed by a safe, powerful interface limited how I could 
>work with what is essentially the same kind of object.

Well, sure, that's the danger of general libraries: you're
getting something that is a decent combination of functionality
and expressiveness contrasted with safety for many needs, but
(almost by definition) not for all needs.  As you point out,
that is useful for many cases, though.

>>>> At first glance it appears that it must suffer from the same
>>>> drawbacks as `XC`, which you mentioned above.  Except that the
>>>> language does provide controlled ways to share data
>>>> concurrently.
>>>>
>>>> Using the _unsafe_ subset, there is one place where it is
>>>> permitted to have multiple, mutable references to an object: the
>>>> `UnsafeCell`.  This gives Rust interior mutability, which means
>>>> that you can build safe abstractions for data sharing, like
>>>> `Mutex` types that own the data they protect.
>>>
>>> If "unsafe" gives enough, but is rarely needed in most code, then it
>>> sounds like a good balance.
>> 
>> Yes.  And moreover, one can hide that unsafety behind a safe
>> interface.
>
>I do like that the unsafety is marked explicitly and clearly.

It goes beyond that, though: _if_ the programmer is successful
in providing a safe abstraction around the unsafety, then it is
impossible to compromise the memory safety of the program by
using that abstraction.  Naturally, "if" is doing a lot of work
here: as I said, the burden for writing `unsafe` code is higher
in Rust than it is in C, and it requires a lot of care.  But the
resulting guarantees are much stronger.

	- Dan C.

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


#399440

FromDavid Brown <david.brown@hesbynett.no>
Date2026-05-26 18:16 +0200
Message-ID<10v4h0n$26qin$1@dont-email.me>
In reply to#399438
On 26/05/2026 16:09, Dan Cross wrote:

(The posts here are getting long, and I think significantly off-topic 
for c.l.c.  I am reading your posts with interest and appreciation, but 
I am afraid it is getting too time-consuming to do justice to them in 
replies.  I've given a somewhat terse reply here, though an even terser 
version would be "I agree with most of it, you've given me lots of 
things to think about, and I really need to learn Rust :-)".  I will 
re-read the post later and may reply more then.)

> In article <10v17h4$18mp3$1@dont-email.me>,
> David Brown  <david.brown@hesbynett.no> wrote:
>> On 24/05/2026 21:08, Dan Cross wrote:
>>> In article <10uprpn$1hfpm$1@dont-email.me>,
>>> David Brown  <david.brown@hesbynett.no> wrote:
>>>> [snip]
>>>> People do sometimes write C code that
>>>> knowingly depends on undefined behaviour, because it makes their results
>>>> more efficient and "it worked when I tested it".
>>>
>>> Yes, or they force some knob on their compiler into the required
>>> position to give them guaranteed results.  Linux does this, for
>>> example; last time I worked in it, Google's massive (2BLOC) code
>>> base similarly.
>>
>> What you then get is code that is UB in C, but not UB in
>> C-with-no-strict-aliasing, or whatever "augmented" language you pick.
> 
> Yes.  An observation pointed out to me at my last gig, and that
> I now point out occasionally myself, is that Linux (for example)
> is not so much written in C but rather in Linux C, which is the
> dialect of the language defined by the compilers they use and
> the specific behaviors they force using flags, pragmas, etc, for
> those compilers.  At any rate, it's certainly not strictly
> conforming ISO C: is _any_ large program strictly conforming at
> this point?  I suspect many projects strive for such, but few
> actually attain it.
> 

I think a lot of code is fully portable C, but very few (if any) real 
programs are.  Even if they don't contain compiler-specific 
requirements, they will generally depend on particular 
implementation-specific behaviours or non-standard libraries and headers.

>> (I have a strict policy of putting any such knobs in "GCC optimize"
>> pragmas, so that the code correctness does not depend on the flags
>> picked in a makefile.  Of course such code remains equally limited in
>> its portability.)
> 
> Good idea, though I like the idea of the compiler failing with a
> usage error if an option is no longer available (or someone is
> trying to build using an old compiler or what have you).
> 

You should get an error (in gcc) for a "#pragma GCC optimize" that is 
not supported.  On the other hand, if you misspell it as "#pragma GCC 
optimise", it will be ignored unless you have "-Wunknown-pragmas" or 
"-Wall" enabled.  And other compilers could silently ignore the GCC 
optimize pragmas.



>>>>> [snip]
>>>>> Hmm.  This reads less like an indictment of the idea of stronger
>>>>> typing, but rather a failure to provide adequate abstractions in
>>>>> the type system.
>>>>
>>>> It is not an indication of problems with stronger typing, but it is an
>>>> indication that the restrictions inherent in the language and tools made
>>>> them somewhat unsuitable for a lot of use-cases that fitted the hardware
>>>> well.  (Modern XMOS tools have changed significantly since those days,
>>>> perhaps partly because of such issues.)
>>>
>>> Sure, but that's a failure of that system to provide good
>>> abstractions: the system was not rich enough to provide the
>>> functionality you needed or wanted.
>>>
>>> I think the central tension here is that the idea of a strong
>>> type system that is also semantically rich is being conflated
>>> with one that's highly restrictive.  What I'm suggesting is that
>>> the opposite is true.
>>
>> To be clear - the restrictions here were not part of the type system.
>> The XC language did have some differences in typing from C, if I
>> remember the details correctly - rather than C pointers it had
>> references which could not be null.  And that's fine.
>>
>> The restrictions were enforced by whole-program analysis.  I think (and
>> you are the Rust expert here, not me) that the Rust borrow checker is
>> similar.  The rules of the language specify aspects of what can and
>> cannot be done with access to data, and these are enforced at a higher
>> level than the main compilation.  They are language rules, but not part
>> of the type system.
> 
> Sorry, let me be clear here: the _language_ is not expressive
> enough to provide the kinds of abstractions that would be useful
> for the types of applications the hardware seems well-suited
> for.

Agreed.

> 
> But the original context was types; my point was that a richer
> langauge can provide the building blocks so that one can build a
> safe abstraction around those kinds of behaviors, even if one
> uses `unsafe` in the implementation of those abstractions.
> 
> This was meant in response to your earlier statement, that e.g.
> performance might cause one to want to reach for `unsafe` to
> work _around_ the language; my point is that the language gives
> you tools to work _with_ it.  That is, the initial desire to
> reach for `unsafe` is _reduced_ by the ability to effectively
> hide it.

Fair enough.

> 
> Implicit in this is a distinction between building what one
> might call infrastructure within one's program, and using that
> infrastructure: the former might involve some controlled (and
> hopefully limited) use of `unsafe`, while the latter ideally
> does not.  I find this is the opposite of what many people
> assume when coming from other language backgrounds, where the
> desire is to push `unsafe` to the point of use; often this is
> because in other languages, building up those abstractions
> requires a lot of machinery with high runtime costs.
> 

I believe we can agree that the ideal should be that "unsafe", or 
equivalent, should not be needed in most code.  My original point was 
just that trying too hard to make a language "safe" without enough care 
for how it will be used can push people towards "unsafe" alternatives. 
But if suitable care is taken, then the result is less unsafe code and 
an overall better language for the task.

>>> [snip]
>>> Not really.  The rule is that borrowing a mutable reference to
>>> some object is mutually exclusive with borrowing any other kind
>>> of reference to that same object at the same time.  `unsafe`
>>> doesn't change that rules, or let the programmer off the hook
>>> for violating it: `unsafe` code isn't allowed to mix mut ref
>>> with other references any more than _safe_ code.  All `unsafe`
>>> means is that the burden of upholding the rules of the language
>>> falls to the programmer, without compiler assistence, because
>>> the programmer knows something that the compiler does not (and
>>> probably cannot) for some reason.
>>
>> That is roughly what I was trying to express, although there is perhaps
>> a grey area between "I am following the rules even though the tools
>> can't see it" and "I am breaking the rules but I know it is safe to do
>> so here without compromising the reason for those rules".
> 
> That's what I'm saying; a program really _doesn't_ get to break
> the rules and retain any guarantee of behavior, unsafe or not.
> In that sense, writing `unsafe` Rust code is _harder_ than
> writing C or another unsafe language.  There is no grey area:
> either the programmer makes sure the program follows the rules,
> or all bets are off.
> 
>> In C (trying desperately to bring us back to c.l.c. :-) ), you might use
>> casts to do something that looks wrong to the compiler, but which you
>> know is safe and correct.
> 
> That's qualitatively different, though.  If, say, I manually
> validate that a pointer points to valid memory, and is properly
> aligned, and so forth, then I can cast that pointer to some
> type.  You can absolutely do that in Rust, too.  But if,
> instead, you say, "I'm going to intentionally invoke UB here..."
> then both languages will bite you.
> 
>>> However, if it really _is_ the case that multiple simultaneous
>>> writes are ok, the ability to create new types and assign them
>>> semantics and behavior menas that a programmer can build a _new_
>>> abstraction that lets them do something similar.  Atomics are
>>> an interesting case in point: one can store to them using a
>>> non-mutable reference: while this seems counter-intuitive at
>>> first, it sort of makes sense for the same reason that a `Mutex`
>>> is accessed via an immutable reference: one cannot observe an
>>> atomic in an intermediate state due to an update, and `load` and
>>> `store` are explicit operations (in practice, the compiler
>>> lowers those to single load/store operations and whatever
>>> barriers are appropriate for the target architecture).
>>
>> OK.  Though that is probably a level of detail that would be clearer to
>> me if I read the Rust documentation first!
>>
>>> A hardware device modeling a framebuffer might be another case;
>>> those are output-only devices, and there's no reason that two
>>> threads cannot write to different parts of the buffer at the
>>> same time, but given a suitable interface, the interface doesn't
>>> need to expose unsafety.  And if you've got a rich type system,
>>> you have the rules to build that interface.
>>
>> That is the kind of thing that was difficult in XC.  Perhaps it would be
>> fair to say that its type system was not powerful enough to work
>> conveniently with its data race and thread safety checking systems.
> 
> Yes.  It also doesn't give you any means to build an abstraction
> that lets you do the thing you want to do.
> 

Indeed.  (And again, let me note that this was my experience with XC a 
long time ago - the tools have changed since then.)

>>>> That does not mean that a language should not try to have such rules,
>>>> and enforce them at compile time - far from it.  The aim should be that
>>>> as much code as possible is correct, or at least immune to particular
>>>> classes of bugs, checked by the compiler and tools.
>>>
>>> I think you're saying something different than what I'm saying;
>>> my point is that the safe interface shouldn't be seen as a
>>> burden and, if well-executed, it shouldn't add a runtime tax in
>>> terms of reduced performance.  You seem to be taking it as a
>>> given that the rules of the language will make both of those
>>> things true, however.
>>
>> I am saying that a safe interface /can/ sometimes be a burden - not that
>> it has to be.
> 
> Well yes, of course; I thought that was a given in the context
> of this discussion.
> 
>> An interface defines what can be done, and also what cannot be done.
>> It's power as an interface comes from both of these - letting you do
>> useful things, and preventing you from doing harmful things.  Sometimes,
>> however, there may be things you want to do that you know are useful and
>> not harmful, but that the interface disallows.  If the language or
>> interface is well designed, and a good fit for the tasks people want to
>> do with the language, then such situations will be minimal.  But I think
>> it is quite easy to fall into a trap when designing an interface where
>> you exclude too many useful cases.  If that happens, then programmers
>> have to use riskier or less efficient workarounds, or find alternative
>> interfaces (or languages).
> 
> Yes.  And what I'm saying is that when working with a language
> that allows you to create useful, robust, types, you can often
> bridge the two worlds and build a new, useful abstraction.  C is
> not a language where one can easily do that; you've got structs,
> unions, and functions...and that's about it.  But you cannot
> restrict the behavior of a struct in the way that King described
> in the "Parse, Don't Validate" piece I linked earlier.
> 

Indeed.  C is not the language of choice for that sort of thing.

> An instance of a struct is Not a proof that some property holds,
> but it _may_ be in Rust or Haskell or OCaml, SML, etc.  I
> suspect one cannot easily do that in C++, because it's not
> managed and doesn't make ownership a first-class property,
> though one can usefully write a number of classes and so forth
> that give much the same effect, if not actual guarantees.

I would say you can do this sort of thing in C++ too, but there are 
perhaps more ways to "cheat" or break promises and guarantees than in in 
some other languages.

> Interestingly (maybe?), I find Ada lacking in this area.

My experience with Ada is not enough to judge your opinion here, but I 
agree this is interesting (and a little surprising).

> 
>> As a concrete example, I recently wanted to use a std::variant<> in my
>> C++ code.  A std::variant<> is, approximately, a struct like :
>>
>> 	struct {
>> 		enum { ... } type_tag;
>> 		union { ... } contents;
>> 	}
>>
>> In C++, this is all type-safe - you don't have direct access to these
>> fields, but instead they are kept consistent automatically so that
>> objects of different types can be stored in the union and have their
>> constructors and destructors called correctly.  But in my case, I wanted
>> to access the fields independently - I wanted to fill the "contents"
>> with data retrieved over a network, and set the "type_tag" according to
>> other data in the network packet.  I knew this was safe (since no
>> constructors or destructors were needed).  But there was no way to
>> handle this within the interface.  My options included a risky,
>> non-portable and difficult workaround (digging through the <variant>
>> header and directly "hacking" the variant object using unsigned char*
>> pointers), serious run-time inefficiencies (with extra copies of the
>> data), or finding a different interface.  I opted for the last one,
>> making my own simple variation of std::variant that gave me the access I
>> needed.
>>
>> This, of course, does not necessarily mean the interface of
>> std::variant<> is bad.  If my needs were highly unusual, then a standard
>> library does not need to support them.  But it is an example where the
>> restrictions imposed by a safe, powerful interface limited how I could
>> work with what is essentially the same kind of object.
> 
> Well, sure, that's the danger of general libraries: you're
> getting something that is a decent combination of functionality
> and expressiveness contrasted with safety for many needs, but
> (almost by definition) not for all needs.  As you point out,
> that is useful for many cases, though.
> 
>>>>> At first glance it appears that it must suffer from the same
>>>>> drawbacks as `XC`, which you mentioned above.  Except that the
>>>>> language does provide controlled ways to share data
>>>>> concurrently.
>>>>>
>>>>> Using the _unsafe_ subset, there is one place where it is
>>>>> permitted to have multiple, mutable references to an object: the
>>>>> `UnsafeCell`.  This gives Rust interior mutability, which means
>>>>> that you can build safe abstractions for data sharing, like
>>>>> `Mutex` types that own the data they protect.
>>>>
>>>> If "unsafe" gives enough, but is rarely needed in most code, then it
>>>> sounds like a good balance.
>>>
>>> Yes.  And moreover, one can hide that unsafety behind a safe
>>> interface.
>>
>> I do like that the unsafety is marked explicitly and clearly.
> 
> It goes beyond that, though: _if_ the programmer is successful
> in providing a safe abstraction around the unsafety, then it is
> impossible to compromise the memory safety of the program by
> using that abstraction.  Naturally, "if" is doing a lot of work
> here: as I said, the burden for writing `unsafe` code is higher
> in Rust than it is in C, and it requires a lot of care.  But the
> resulting guarantees are much stronger.
> 
> 	- Dan C.
> 

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


#399687

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2026-06-04 07:19 -0700
Message-ID<86se72bd74.fsf@linuxsc.com>
In reply to#399438
cross@spitfire.i.gajendra.net (Dan Cross) writes:

> [...] An observation pointed out to me at my last gig, and that
> I now point out occasionally myself, is that Linux (for example)
> is not so much written in C but rather in Linux C, which is the
> dialect of the language defined by the compilers they use and
> the specific behaviors they force using flags, pragmas, etc, for
> those compilers.

Any program accepted by a conforming implementation is a C program.
That remains true even if the program relies on compiler options
such as -fwrap or -fno-strict-aliasing, or takes advantage of
specific behaviors chosen by the compiler in situations that the C
standard deems undefined behavior, or uses non-standard #pragmas
that the implementation has chosen to define.  As long as the
implementation stays inside the bounds of being conforming, any
program it accepts is written in C.  Writing in a subset of the full
language doesn't change that:  a C program that has no 'goto'
statements in it is still a C program.  The same reasoning applies
to programs that make use of -fwrapv, etc.

> At any rate, it's certainly not strictly
> conforming ISO C:  is _any_ large program strictly conforming at
> this point?  I suspect many projects strive for such, but few
> actually attain it.

I expect most people don't realize how high a bar it is to write a C
program that is strictly conforming.  Except for toy examples I
don't think I've ever seen one.  I wouldn't advocate choosing such a
criterion.  Even more than that, if a member of any team I was part
of did suggest doing so I would strongly argue against it.  Even if
it could be done, which I think is unlikely, the amount of effort
needed to do so would be prohibitive.

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


#399695

Fromcross@spitfire.i.gajendra.net (Dan Cross)
Date2026-06-04 17:18 +0000
Message-ID<10vsc1i$iht$1@reader1.panix.com>
In reply to#399687
In article <86se72bd74.fsf@linuxsc.com>,
Tim Rentsch  <tr.17687@z991.linuxsc.com> wrote:
>cross@spitfire.i.gajendra.net (Dan Cross) writes:
>> [...] An observation pointed out to me at my last gig, and that
>> I now point out occasionally myself, is that Linux (for example)
>> is not so much written in C but rather in Linux C, which is the
>> dialect of the language defined by the compilers they use and
>> the specific behaviors they force using flags, pragmas, etc, for
>> those compilers.
>
>Any program accepted by a conforming implementation is a C program.
>That remains true even if the program relies on compiler options
>such as -fwrap or -fno-strict-aliasing, or takes advantage of
>specific behaviors chosen by the compiler in situations that the C
>standard deems undefined behavior, or uses non-standard #pragmas
>that the implementation has chosen to define.  As long as the
>implementation stays inside the bounds of being conforming, any
>program it accepts is written in C.  Writing in a subset of the full
>language doesn't change that:  a C program that has no 'goto'
>statements in it is still a C program.  The same reasoning applies
>to programs that make use of -fwrapv, etc.

This is quibbling, but for the record, Linux is written in an
_extended_ subset of ISO C, and makes use of a number of
non-conforming extensions (e.g., GCC-style function attributes
and so on).  While it's obviously "C" in some generic sense,
describing it as a dialect called "Linux C" is entirely
appropriate.

But don't take my word for it: I urge you to have a look at the
code and draw your own conclusion.

>> At any rate, it's certainly not strictly
>> conforming ISO C:  is _any_ large program strictly conforming at
>> this point?  I suspect many projects strive for such, but few
>> actually attain it.
>
>I expect most people don't realize how high a bar it is to write a C
>program that is strictly conforming.  Except for toy examples I
>don't think I've ever seen one.  I wouldn't advocate choosing such a
>criterion.  Even more than that, if a member of any team I was part
>of did suggest doing so I would strongly argue against it.  Even if
>it could be done, which I think is unlikely, the amount of effort
>needed to do so would be prohibitive.

Agreed.

	- Dan C.

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


#399250

Fromscott@slp53.sl.home (Scott Lurndal)
Date2026-05-21 15:04 +0000
Message-ID<paFPR.9635$MQ1.2513@fx37.iad>
In reply to#399244
cross@spitfire.i.gajendra.net (Dan Cross) writes:

>Similarly, the RAII idiom prevalent in C++ and Rust uses object
>destructors that are automatically run when something goes out
>of scope to do the cleanup.  C++ pairs that with
>exceptions (arguably worse than goto) while Rust represents
>errors with sum types and a little bit of syntactic sugar with
>the `?` operator.  In either case, the descriptors run and do
>the cleanup, regardless of whether the return was an error path
>or a success path.

We used this in 1990 when implementing a fork() function in
an unix-compatible distributed operating system (although it
wasn't known formally as RAII in those days).

int
tProc::Fork(KnCap* PActUI, int Caller, tLwp *CrLwp, int IsVFork, boolean_t ForkAll)
{
        int Error = 0;
        int nlwp;       // total number of active lwps in the child
        int total_lwp;  // total number of lwps in the child (active + zombies)

        ASSERT((Caller == FORK_SYSCALL) || (Caller == FORK_BOOTPROC));

        KnCap *ChildCap = Actor.GetCap();

        // Hand crafted processes do not have a ParentP.
        tProc *ParentP = CrLwp->MyProc();

        // Initialise the global Ops event that is used for global Ops
        // synchronisation

        EVENT_INIT(&GlobalEvt);

        //
        // Only Single threaded processes can vfork().
        // Currently, we don't support vfork.
        if (IsVFork && (!(ParentP->LwpList.SingleThreaded()))) {
                return EINVAL;
        }

        if (ForkAll) {
                nlwp = ParentP->LwpList.GetCountLwp();
                total_lwp = ParentP->LwpList.GetTotalLwp();

        } else {
                nlwp = 1;
                total_lwp = 1;
        }

        //
        // Check to see if we will be exceeding the quota.
        // XXXKYS: Check the interface for picking up quota tokens.
        // Would prefer an interface that accepted the number of 
        // tokens needed - proc + lwps.
        // NOTE: The number of LWP tokens picked up will be equal to the 
        // total number of LWPs in the child (including zombie LWPs).

        if (UidQuota.Fork(ProcCred->GetUid(), ProcCred->GetEuid(), total_lwp)) {
                return EAGAIN;
        }

        tForkFailure ff(this, CrLwp, ChildCap, nlwp, total_lwp);
    .
    .
    .
}

=== The tForkfailure class encapsulated the resources allocated
    to the thread.  The fork function could return at any time
    after this and the destructor for tForkFailure would clean up
    any allocated resources.

//
//      Destructor: undo what fork has done upon failure.
//
tForkFailure::~tForkFailure()
{
        if (ret == 0) {
                return;
        }

        if (PActUI != NULL) {
                procp->Mem.Exit(ChildCap);
        }

                //
                // XXXKYS: the DeleteAll() needs to take 
                // into account that some of the LWPs
                // in the list may be zombies.
                //
        procp->LwpList.DeleteAll();

        if (rgn == B_TRUE) {
                procp->Rgn.ShmExit(CrLwp, procp);
        }

        if (semundo == B_TRUE) {
                procp->Undo.SemUnFork();
        }

        if (file == B_TRUE) {
                procp->File.ForkUndo();
        }

        procp->ProcRlim->rlFree(nlwp + 1);
        procp->ProcCred->CrFree(nlwp + 1);

        procp->UidQuota.FreeProc(B_TRUE, total_lwp, 1);
}

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


#399229

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2026-05-20 16:47 -0700
Message-ID<10ulh7g$coh9$1@dont-email.me>
In reply to#399218
On 5/20/2026 8:18 AM, Dan Cross wrote:
> In article <10ujm3r$3pnbb$1@dont-email.me>,
> David Brown  <david.brown@hesbynett.no> wrote:
>> [snip] I have almost never had need of "goto" or labels (excluding
>> switch case labels, of course), and don't expect ever to do so in the
>> future.
> 
> While I generally try to avoid it, there are times (in C in
> particular) when it really is the right tool; the inventors of C
> understood that.  From the Plan 9 `fortunes` file: "If you want
> to go somewhere, goto is the best way to get there. K Thompson"

Oh shit. Side note. Did you ever hear about a nasty race condition in 
Plan 9 wrt some lock-free thing, or even a mutex acquisition? The Plan9 
problem. I remember conversing about with with Alex Terekhov way back in 
comp.programming.threads.

[...]

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


Page 8 of 13 — ← Prev page 1 … 6 7 [8] 9 10 … 13  Next page →

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


csiph-web