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


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

Prioritize Performance over Correctness

Started byJanis Papanagnou <janis_papanagnou+ng@hotmail.com>
First post2026-07-22 01:38 +0200
Last post2026-07-23 11:18 +0200
Articles 20 on this page of 186 — 20 participants

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


Contents

  Prioritize Performance over Correctness Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-07-22 01:38 +0200
    Re: Prioritize Performance over Correctness Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-21 17:26 -0700
      Re: Prioritize Performance over Correctness cross@spitfire.i.gajendra.net (Dan Cross) - 2026-07-22 01:50 +0000
        Re: Prioritize Performance over Correctness Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-21 20:25 -0700
          Re: Prioritize Performance over Correctness cross@spitfire.i.gajendra.net (Dan Cross) - 2026-07-22 17:37 +0000
        Re: Prioritize Performance over Correctness "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-07-22 13:26 -0700
      Re: Prioritize Performance over Correctness Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-07-22 07:33 +0200
        Re: Prioritize Performance over Correctness David Brown <david.brown@hesbynett.no> - 2026-07-22 10:41 +0200
          Re: Prioritize Performance over Correctness BGB <cr88192@gmail.com> - 2026-07-22 18:08 -0500
            Re: Prioritize Performance over Correctness David Brown <david.brown@hesbynett.no> - 2026-07-23 10:31 +0200
              Re: Prioritize Performance over Correctness Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-23 14:31 -0700
                Re: Prioritize Performance over Correctness Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-23 14:48 -0700
                  Re: Prioritize Performance over Correctness Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-23 15:11 -0700
                    Re: Prioritize Performance over Correctness David Brown <david.brown@hesbynett.no> - 2026-07-24 09:23 +0200
                      Re: Prioritize Performance over Correctness Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-24 03:14 -0700
                      Re: Prioritize Performance over Correctness scott@slp53.sl.home (Scott Lurndal) - 2026-07-24 14:56 +0000
                      Re: Prioritize Performance over Correctness antispam@fricas.org (Waldek Hebisch) - 2026-07-25 16:30 +0000
                        Re: Prioritize Performance over Correctness James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-07-27 09:33 -0400
                          Re: Prioritize Performance over Correctness Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-07-28 00:22 +0800
                            Re: Prioritize Performance over Correctness Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-27 12:58 -0700
                              Re: Prioritize Performance over Correctness BGB <cr88192@gmail.com> - 2026-07-27 15:37 -0500
                                Re: Prioritize Performance over Correctness James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-07-27 17:13 -0400
                                  Re: Prioritize Performance over Correctness Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-27 15:17 -0700
                                    Re: Prioritize Performance over Correctness scott@slp53.sl.home (Scott Lurndal) - 2026-07-28 01:18 +0000
                                      Re: Prioritize Performance over Correctness Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-07-28 15:40 +0800
                                        Re: Prioritize Performance over Correctness cross@spitfire.i.gajendra.net (Dan Cross) - 2026-07-28 14:18 +0000
                                          Multics( Re: Prioritize Performance over Correctness) Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-07-28 22:48 +0800
                                            Re: Multics( Re: Prioritize Performance over Correctness) scott@slp53.sl.home (Scott Lurndal) - 2026-07-28 15:08 +0000
                                              Re: Multics( Re: Prioritize Performance over Correctness) Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-07-28 23:30 +0800
                                                Re: Multics( Re: Prioritize Performance over Correctness) cross@spitfire.i.gajendra.net (Dan Cross) - 2026-07-28 19:08 +0000
                                                  Re: Multics( Re: Prioritize Performance over Correctness) Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-07-29 04:08 +0800
                                                    Re: Multics( Re: Prioritize Performance over Correctness) cross@spitfire.i.gajendra.net (Dan Cross) - 2026-07-28 22:15 +0000
                                                    Re: Multics( Re: Prioritize Performance over Correctness) cross@spitfire.i.gajendra.net (Dan Cross) - 2026-07-28 22:26 +0000
                                                      Re: Multics( Re: Prioritize Performance over Correctness) Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-07-29 06:41 +0800
                                                        Re: Multics( Re: Prioritize Performance over Correctness) cross@spitfire.i.gajendra.net (Dan Cross) - 2026-07-28 23:23 +0000
                                                          Picture of Organicks' book Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-07-29 16:01 +0800
                                                            Re: Picture of Organicks' book cross@spitfire.i.gajendra.net (Dan Cross) - 2026-07-29 13:46 +0000
                                                              Re: Picture of Organicks' book R Kym Horsell <kymhorsell@gmail.com> - 2026-07-29 16:54 +0000
                                                          Re: Multics( Re: Prioritize Performance over Correctness) Cóilín Nioclásín Glostéir <thanks-to@Taf.com> - 2026-07-29 23:22 +0000
                                              Re: Multics( Re: Prioritize Performance over Correctness) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-08-15 15:55 -0700
                                            Re: Multics( Re: Prioritize Performance over Correctness) cross@spitfire.i.gajendra.net (Dan Cross) - 2026-07-28 18:58 +0000
                                              Re: Multics( Re: Prioritize Performance over Correctness) Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-07-29 04:10 +0800
                                                Re: Multics( Re: Prioritize Performance over Correctness) cross@spitfire.i.gajendra.net (Dan Cross) - 2026-07-28 22:20 +0000
                                                  Re: Multics( Re: Prioritize Performance over Correctness) scott@slp53.sl.home (Scott Lurndal) - 2026-07-29 14:44 +0000
                                                    Re: Multics( Re: Prioritize Performance over Correctness) cross@spitfire.i.gajendra.net (Dan Cross) - 2026-07-30 02:08 +0000
                                    Re: Prioritize Performance over Correctness Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-08-16 07:59 -0700
                              Re: Prioritize Performance over Correctness Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-27 17:59 -0700
                                Re: Prioritize Performance over Correctness Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-07-28 15:42 +0800
                                  Re: Prioritize Performance over Correctness Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-28 03:22 -0700
                                    Re: Prioritize Performance over Correctness Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-07-28 19:21 +0800
                                      Re: Prioritize Performance over Correctness bart <bc@freeuk.com> - 2026-07-28 13:02 +0100
                                        Re: Prioritize Performance over Correctness Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-07-28 20:18 +0800
                                          Re: Prioritize Performance over Correctness bart <bc@freeuk.com> - 2026-07-28 14:17 +0100
                                            Re: Prioritize Performance over Correctness BGB <cr88192@gmail.com> - 2026-07-28 16:02 -0500
                                            Re: Prioritize Performance over Correctness Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-07-29 16:45 +0800
                                              Re: Prioritize Performance over Correctness bart <bc@freeuk.com> - 2026-07-29 12:03 +0100
                                                Re: Prioritize Performance over Correctness Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-07-29 19:32 +0800
                                                  Re: Prioritize Performance over Correctness bart <bc@freeuk.com> - 2026-07-29 13:42 +0100
                                                    Re: Prioritize Performance over Correctness Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-07-29 20:49 +0800
                                                      Re: Prioritize Performance over Correctness bart <bc@freeuk.com> - 2026-07-29 16:01 +0100
                                                Re: Prioritize Performance over Correctness Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-29 12:53 -0700
                                                Re: Prioritize Performance over Correctness James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-07-31 14:21 -0400
                                                  Re: Prioritize Performance over Correctness bart <bc@freeuk.com> - 2026-07-31 20:07 +0100
                                                    Re: Prioritize Performance over Correctness Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-31 13:00 -0700
                                                    Re: Prioritize Correctness Over Performance Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-08-01 02:34 +0000
                                        Re: Prioritize Performance over Correctness Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-28 16:08 -0700
                                          Re: Prioritize Performance over Correctness cross@spitfire.i.gajendra.net (Dan Cross) - 2026-07-28 23:28 +0000
                                      Re: Prioritize Performance over Correctness cross@spitfire.i.gajendra.net (Dan Cross) - 2026-07-28 14:22 +0000
                                      Re: Prioritize Performance over Correctness "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-07-28 13:51 -0700
                                      Re: Prioritize Performance over Correctness James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-07-28 20:32 -0400
                                    Re: Prioritize Performance over Correctness cross@spitfire.i.gajendra.net (Dan Cross) - 2026-07-28 14:20 +0000
                                  Re: Prioritize Performance over Correctness "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-07-28 13:54 -0700
                                    Re: Prioritize Performance over Correctness Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-07-29 05:00 +0800
                                      Re: Prioritize Performance over Correctness James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-07-28 20:25 -0400
                                        Re: Prioritize Performance over Correctness "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-07-29 14:55 -0700
                                      Re: Prioritize Performance over Correctness James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-07-28 20:31 -0400
                                        Re: Prioritize Performance over Correctness Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-28 21:26 -0700
                                          Re: Prioritize Performance over Correctness "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-07-29 14:57 -0700
                                            Re: Prioritize Performance over Correctness Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-29 15:33 -0700
                                              Re: Prioritize Performance over Correctness "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-07-29 16:22 -0700
                                              Re: Prioritize Performance over Correctness Richard Harnden <richard.nospam@gmail.invalid> - 2026-07-30 07:40 +0100
                                                Re: Prioritize Correctness over Performance Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-07-30 06:48 +0000
                                                  Re: Prioritize Correctness over Performance James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-07-30 06:50 -0400
                                                  Re: Prioritize Correctness over Performance Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-30 03:54 -0700
                                                    Re: Prioritize Correctness over Performance James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-07-30 08:24 -0400
                                                      Re: Prioritize Correctness over Performance Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-30 14:40 -0700
                                                  Re: Prioritize Correctness over Performance "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-07-30 19:39 -0700
                                                Re: Prioritize Performance over Correctness James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-07-30 06:44 -0400
                                                  Re: Prioritize Performance over Correctness Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-07-30 21:00 +0000
                                                    Re: Prioritize Performance over Correctness Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-30 14:38 -0700
                                                    Re: Prioritize Performance over Correctness Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-07-30 21:53 +0000
                                                      Re: Prioritize Performance over Correctness Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-30 15:10 -0700
                                                    Re: Prioritize Performance over Correctness "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-07-30 19:40 -0700
                                                      Re: Prioritize Performance over Correctness cross@spitfire.i.gajendra.net (Dan Cross) - 2026-07-31 02:43 +0000
                                                        Re: Prioritize Performance over Correctness "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-07-30 19:44 -0700
                                                          Re: Prioritize Performance over Correctness "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-07-30 19:58 -0700
                                                          Re: Prioritize Performance over Correctness "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-08-01 01:25 -0700
                                                            Re: Prioritize Performance over Correctness David Brown <david.brown@hesbynett.no> - 2026-08-02 23:14 +0200
                                                              Re: Prioritize Performance over Correctness "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-08-02 14:37 -0700
                                                                Re: Prioritize Performance over Correctness Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-08-02 22:51 +0000
                                                                  Re: Prioritize Performance over Correctness Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-08-02 16:43 -0700
                                                                  Re: Prioritize Performance over Correctness "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-08-03 12:03 -0700
                                                                    Re: Prioritize Correctness Over Performance Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-08-03 23:49 +0000
                                                                      Re: Prioritize Correctness Over Performance "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-08-03 19:35 -0700
                                                                MS-DOS memory models (was: Re: Prioritize Performance over Correctness) Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-08-03 08:08 +0800
                                                                Re: Prioritize Performance over Correctness David Brown <david.brown@hesbynett.no> - 2026-08-03 10:16 +0200
                                                                  Re: Prioritize Performance over Correctness Richard Harnden <richard.nospam@gmail.invalid> - 2026-08-03 10:41 +0100
                                                                    Re: Prioritize Performance over Correctness David Brown <david.brown@hesbynett.no> - 2026-08-03 12:28 +0200
                                                                      Malicious Computer Architecture (was: Re: Prioritize Performance over Correctness) Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-08-03 19:23 +0800
                                                                        Re: Malicious Computer Architecture David Brown <david.brown@hesbynett.no> - 2026-08-03 14:01 +0200
                                                                          Re: Malicious Computer Architecture Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-08-03 22:52 +0800
                                                                            Re: Malicious Computer Architecture David Brown <david.brown@hesbynett.no> - 2026-08-03 19:41 +0200
                                                                              Re: Malicious Computer Architecture "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-08-03 13:13 -0700
                                                                            Re: Malicious Computer Architecture "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-08-03 13:10 -0700
                                                                        Re: Malicious Computer Architecture (was: Re: Prioritize Performance over Correctness) scott@slp53.sl.home (Scott Lurndal) - 2026-08-03 14:29 +0000
                                                                        Johnny Depp prevention [Windows 11 etc...] (Was: Malicious Computer Architecture) Mild Shock <janburse@fastmail.fm> - 2026-08-03 18:10 +0200
                                                                          But how can you deploy. when its ROM? (Was: Johnny Depp prevention [Windows 11 etc...]) Mild Shock <janburse@fastmail.fm> - 2026-08-03 18:15 +0200
                                                                            GPU Elasticity: Collective Communications Libraries (Was: But how can you deploy. when its ROM?) Mild Shock <janburse@fastmail.fm> - 2026-08-07 14:37 +0200
                                                                              What are Flits and Phits? [Network on a Chip] (Re: GPU Elasticity: Collective Communications Libraries) Mild Shock <janburse@fastmail.fm> - 2026-08-07 18:07 +0200
                                                                                Cristallina: Thank you for the Beam (Re: What are Flits and Phits? [Network on a Chip]) Mild Shock <janburse@fastmail.fm> - 2026-08-09 21:22 +0200
                                                                                  Loderunner Enemy AI better than SWI-Prolog? [Prolog Education Group] Mild Shock <janburse@fastmail.fm> - 2026-08-18 16:26 +0200
                                                                                    How to shoot yourself in the foot (Re: Loderunner Enemy AI better than SWI-Prolog? [Prolog Education Group] Mild Shock <janburse@fastmail.fm> - 2026-08-18 16:50 +0200
                                                                                      Re: How to shoot yourself in the foot (Re: Loderunner Enemy AI better than SWI-Prolog? [Prolog Education Group] Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-08-19 03:24 +0800
                                                                                    Re: Loderunner Enemy AI better than SWI-Prolog? [Prolog Education Group] Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-08-19 03:21 +0800
                                                                                      Re: Loderunner Enemy AI better than SWI-Prolog? [Prolog Education Group] Aidan Kehoe <kehoea@parhasard.net> - 2026-08-18 21:13 +0100
                                                                                        Re: Loderunner Enemy AI better than SWI-Prolog? [Prolog Education Group] Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-08-18 22:49 +0000
                                                                                          Re: Loderunner Enemy AI better than SWI-Prolog? [Prolog Education Group] Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-08-19 08:32 +0800
                                                                                        Re: Loderunner Enemy AI better than SWI-Prolog? [Prolog Education Group] Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-08-19 08:27 +0800
                                                                                The Mac Neo is a Budget Monster [GPU Channels] (Re: What are Flits and Phits? [Network on a Chip]) Mild Shock <janburse@fastmail.fm> - 2026-08-11 16:27 +0200
                                                                                  The luminaries of duct-tape engineering [Sweeney and Torvald] (Was: The Mac Neo is a Budget Monster [GPU Channels]) Mild Shock <janburse@fastmail.fm> - 2026-08-11 16:51 +0200
                                                                        Re: Malicious Computer Architecture Aidan Kehoe <kehoea@parhasard.net> - 2026-08-03 19:51 +0100
                                                                          Re: Malicious Computer Architecture Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-08-05 00:22 +0800
                                                                            Re: Malicious Computer Architecture Richard Harnden <richard.nospam@gmail.invalid> - 2026-08-04 19:10 +0100
                                                                              Re: Malicious Computer Architecture Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-08-05 03:21 +0800
                                                                            Re: Malicious Computer Architecture Kaz Kylheku <046-301-5902@kylheku.com> - 2026-08-06 21:55 +0000
                                                                              Re: Malicious Computer Architecture Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-08-07 06:31 +0800
                                                                            Re: Malicious Computer Architecture Aidan Kehoe <kehoea@parhasard.net> - 2026-08-06 23:01 +0100
                                                                        A Case for Impurity: The Applied Pi Calculus (Re: Malicious Computer Architecture) Mild Shock <janburse@fastmail.fm> - 2026-08-04 14:58 +0200
                                                                          The Sandcastle of Paul Taraus Interactors (Re: A Case for Impurity: The Applied Pi Calculus) Mild Shock <janburse@fastmail.fm> - 2026-08-04 15:10 +0200
                                                                    Re: Prioritize Performance over Correctness Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-08-03 05:34 -0700
                                                                    Re: Prioritize Performance over Correctness "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-08-03 13:04 -0700
                                                                      Re: Prioritize Correctness Over Performance Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-08-04 00:52 +0000
                                                                        Re: Prioritize Correctness Over Performance scott@slp53.sl.home (Scott Lurndal) - 2026-08-04 14:22 +0000
                                                                  Re: Prioritize Performance over Correctness Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-08-03 05:25 -0700
                                                                    Re: Prioritize Performance over Correctness David Brown <david.brown@hesbynett.no> - 2026-08-03 15:10 +0200
                                                                    Re: Prioritize Performance over Correctness "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-08-03 13:16 -0700
                                                            Re: Prioritize Performance over Correctness James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-08-03 20:29 -0400
                                                              Re: Prioritize Performance over Correctness Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-08-03 17:55 -0700
                                                                Re: Prioritize Performance over Correctness David Brown <david.brown@hesbynett.no> - 2026-08-04 09:12 +0200
                                                    Re: Prioritize Performance over Correctness Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-08-02 19:01 -0700
                                                      Re: Prioritize Performance over Correctness cross@spitfire.i.gajendra.net (Dan Cross) - 2026-08-03 19:59 +0000
                                                Re: Prioritize Performance over Correctness Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-30 03:50 -0700
                                      Re: Prioritize Performance over Correctness "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-07-29 15:09 -0700
                              Re: Prioritize Performance over Correctness Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-07-28 08:14 +0800
                                Re: Prioritize Performance over Correctness Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-07-29 05:54 +0800
                                  Re: Prioritize Performance over Correctness steveo@panix.com (Steven M. O'Neill) - 2026-07-31 20:34 +0000
                                Re: Prioritize Performance over Correctness James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-07-28 19:40 -0400
                            Re: Prioritize Performance over Correctness BGB <cr88192@gmail.com> - 2026-07-27 15:36 -0500
                              Re: Prioritize Performance over Correctness Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-07-29 04:56 +0800
                Re: Prioritize Performance over Correctness Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-07-24 14:47 +0200
                  Re: Prioritize Performance over Correctness David Brown <david.brown@hesbynett.no> - 2026-07-24 16:27 +0200
                  Resources for Amateur Compiler Writers Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-07-25 00:52 +0800
                    Re: Resources for Amateur Compiler Writers bart <bc@freeuk.com> - 2026-07-24 23:08 +0100
                      Re: Resources for Amateur Compiler Writers BGB <cr88192@gmail.com> - 2026-07-24 18:50 -0500
                      Re: Resources for Amateur Compiler Writers Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-07-25 01:54 +0000
                        Re: Resources for Amateur Compiler Writers Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-07-25 15:20 +0800
                          Re: Resources for Amateur Compiler Writers Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-07-25 07:24 +0000
                            Re: Resources for Amateur Compiler Writers Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-07-25 15:30 +0800
                              Re: Resources for Amateur Compiler Writers David Brown <david.brown@hesbynett.no> - 2026-07-25 10:37 +0200
                                Re: Resources for Amateur Compiler Writers Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-07-27 00:35 +0800
                                  Re: Resources for Amateur Compiler Writers BGB <cr88192@gmail.com> - 2026-07-26 12:39 -0500
                                    Re: Resources for Amateur Compiler Writers bart <bc@freeuk.com> - 2026-07-26 22:27 +0100
                                      Re: Resources for Amateur Compiler Writers BGB <cr88192@gmail.com> - 2026-07-26 18:02 -0500
                              Re: Resources for Amateur Compiler Writers Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-07-25 22:32 +0000
                                Re: Resources for Amateur Compiler Writers Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-25 15:58 -0700
                      Re: Resources for Amateur Compiler Writers David Brown <david.brown@hesbynett.no> - 2026-07-25 10:23 +0200
                    Re: Resources for Amateur Compiler Writers Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-24 16:29 -0700
                      Re: Resources for Amateur Compiler Writers Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-07-25 15:25 +0800
                        Re: Resources for Amateur Compiler Writers Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-25 15:33 -0700
                          Re: Resources for Amateur Compiler Writers Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-07-27 00:38 +0800
                            Re: Resources for Amateur Compiler Writers Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-26 17:06 -0700
                    Re: Resources for Amateur Compiler Writers Cóilín Nioclásín Glostéir <thanks-to@Taf.com> - 2026-07-26 17:03 +0000
                  Re: Prioritize Performance over Correctness BGB <cr88192@gmail.com> - 2026-07-24 16:50 -0500
                  Re: Prioritize Performance over Correctness Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-07-24 16:13 -0700
              Re: Prioritize Performance over Correctness BGB <cr88192@gmail.com> - 2026-07-26 15:26 -0500
          Re: Prioritize Performance over Correctness Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-07-23 11:18 +0200

Page 1 of 10  [1] 2 3 … 10  Next page →


#400344 — Prioritize Performance over Correctness

FromJanis Papanagnou <janis_papanagnou+ng@hotmail.com>
Date2026-07-22 01:38 +0200
SubjectPrioritize Performance over Correctness
Message-ID<113ovuj$23t9c$1@dont-email.me>
There was some recent longish thread with discussions addressing
Undefined Behavior. I just stumbled across a paper from Russ Cox
on that topic with a provoking title.[*] I don't recall whether
that had already been referenced anywhere in that thread; if not
it might be of interest to some. A couple arguments and examples
look familiar already, but I think it may be valuable anyway.

Janis

[*] https://research.swtch.com/ub

[toc] | [next] | [standalone]


#400345

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2026-07-21 17:26 -0700
Message-ID<113p2o1$2es3m$1@kst.eternal-september.org>
In reply to#400344
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
> There was some recent longish thread with discussions addressing
> Undefined Behavior. I just stumbled across a paper from Russ Cox
> on that topic with a provoking title.[*] I don't recall whether
> that had already been referenced anywhere in that thread; if not
> it might be of interest to some. A couple arguments and examples
> look familiar already, but I think it may be valuable anyway.
>
> Janis
>
> [*] https://research.swtch.com/ub

For those who don't follow the link, the full title of the paper is
"C and C++ Prioritize Performance over Correctness".  (Your
paraphrase could be interpreted as advice, which I'm sure is not
how you intended it.)

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */

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


#400346

Fromcross@spitfire.i.gajendra.net (Dan Cross)
Date2026-07-22 01:50 +0000
Message-ID<113p7k8$27o$1@reader1.panix.com>
In reply to#400345
In article <113p2o1$2es3m$1@kst.eternal-september.org>,
Keith Thompson  <Keith.S.Thompson+u@gmail.com> wrote:
>Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
>> There was some recent longish thread with discussions addressing
>> Undefined Behavior. I just stumbled across a paper from Russ Cox
>> on that topic with a provoking title.[*] I don't recall whether
>> that had already been referenced anywhere in that thread; if not
>> it might be of interest to some. A couple arguments and examples
>> look familiar already, but I think it may be valuable anyway.
>>
>> Janis
>>
>> [*] https://research.swtch.com/ub
>
>For those who don't follow the link, the full title of the paper is
>"C and C++ Prioritize Performance over Correctness".  (Your
>paraphrase could be interpreted as advice, which I'm sure is not
>how you intended it.)

From the post:

```
term% cat eraseall.c
#include <stdio.h>
#include <stdlib.h>

typedef void (*Function)(void);

static Function Do;

static void
baz(void)
{
    printf("baz invoked.\n");
}

static void
bar(void)
{
    baz();
}

void
foo(void)
{
    Do = bar;
}

int
main(void)
{
    Do();
    return 0;
}

term% clang -O1 -Wall -Wextra -pedantic -std=c23 -o eraseall eraseall.c
term% ./eraseall
baz invoked.
term% 
```

Something similar came up a month or so ago; recall my "what.c"
program:

```
term% cat what.c
#include <stdio.h>
int main(void) { for (unsigned int k = 0; k != 1; k += 2){} return 0; }
void hello(void) { printf("Hello, World!\n"); }
term% clang -O1 -Wall -Werror -pedantic -pedantic-errors -std=c23 -o what what.c
term% ./what
Hello, World!
term% 
```

It's notable that the quoted text for the ANSI C standard also
says that an implementation is free to abort translation if it
encounters UB, which I recall was something that was a point of
concention in the earlier discussion.  Kuyper posted a link to
a defect report that suggested that the compiler had to
translate the program if it could prove that (in that case,
manifest) UB was never triggered; however, that was from 1994,
and not normative anyhow.  The committee has had ample time to
tune up the writing about this in the standard, and has chosen
not to: Cox's post is on-point; the current standard is deeply
flawed.

	- Dan C.

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


#400347

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2026-07-21 20:25 -0700
Message-ID<113pd7i$2hns9$1@kst.eternal-september.org>
In reply to#400346
cross@spitfire.i.gajendra.net (Dan Cross) writes:
[...]
> ```
> term% cat eraseall.c
> #include <stdio.h>
> #include <stdlib.h>
>
> typedef void (*Function)(void);
>
> static Function Do;
>
> static void
> baz(void)
> {
>     printf("baz invoked.\n");
> }
>
> static void
> bar(void)
> {
>     baz();
> }
>
> void
> foo(void)
> {
>     Do = bar;
> }
>
> int
> main(void)
> {
>     Do();
>     return 0;
> }
>
> term% clang -O1 -Wall -Wextra -pedantic -std=c23 -o eraseall eraseall.c
> term% ./eraseall
> baz invoked.
> term% 
> ```

In that program, Do is a function pointer that's initialized to a null
pointer value (because it's static), so the call `Do()` has undefined
behavior.

> Something similar came up a month or so ago; recall my "what.c"
> program:
>
> ```
> term% cat what.c
> #include <stdio.h>
> int main(void) { for (unsigned int k = 0; k != 1; k += 2){} return 0; }
> void hello(void) { printf("Hello, World!\n"); }
> term% clang -O1 -Wall -Werror -pedantic -pedantic-errors -std=c23 -o what what.c
> term% ./what
> Hello, World!
> term% 
> ```

That's an example of something more specific.  N3220 6.8.6.1p4
gives explicit permission for an implementation to "assume" that
certain iteration statements will terminate.  (I've said before
that I dislike this rule for several reasons.)

> It's notable that the quoted text for the ANSI C standard also
> says that an implementation is free to abort translation if it
> encounters UB, which I recall was something that was a point of
> concention in the earlier discussion.  Kuyper posted a link to
> a defect report that suggested that the compiler had to
> translate the program if it could prove that (in that case,
> manifest) UB was never triggered; however, that was from 1994,
> and not normative anyhow.

C89 and all later editions of the C standard say (in a non-normative
note) that undefined behavior can include "terminating a
translation or execution (with the issuance of a diagnostic
message)".  But almost all undefined behavior occurs at run time.
That could have been worded more clearly, but my interpretation
is that an implementation that detects that a source construct
has undefined behavior can terminate translation only if it can
prove that it's always executed.  `if (0) 1/0;` does not permit
terminating translation.

>                            The committee has had ample time to
> tune up the writing about this in the standard, and has chosen
> not to: Cox's post is on-point; the current standard is deeply
> flawed.

How would you suggest fixing it?

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */

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


#400351

Fromcross@spitfire.i.gajendra.net (Dan Cross)
Date2026-07-22 17:37 +0000
Message-ID<113qv3t$ma0$1@reader1.panix.com>
In reply to#400347
In article <113pd7i$2hns9$1@kst.eternal-september.org>,
Keith Thompson  <Keith.S.Thompson+u@gmail.com> wrote:
>cross@spitfire.i.gajendra.net (Dan Cross) writes:
>[...]
>> ```
>> term% cat eraseall.c
>> #include <stdio.h>
>> #include <stdlib.h>
>>
>> typedef void (*Function)(void);
>>
>> static Function Do;
>>
>> static void
>> baz(void)
>> {
>>     printf("baz invoked.\n");
>> }
>>
>> static void
>> bar(void)
>> {
>>     baz();
>> }
>>
>> void
>> foo(void)
>> {
>>     Do = bar;
>> }
>>
>> int
>> main(void)
>> {
>>     Do();
>>     return 0;
>> }
>>
>> term% clang -O1 -Wall -Wextra -pedantic -std=c23 -o eraseall eraseall.c
>> term% ./eraseall
>> baz invoked.
>> term% 
>> ```
>
>In that program, Do is a function pointer that's initialized to a null
>pointer value (because it's static), so the call `Do()` has undefined
>behavior.

Yup.  UB gives the compiler permission to go wild.

>> Something similar came up a month or so ago; recall my "what.c"
>> program:
>>
>> ```
>> term% cat what.c
>> #include <stdio.h>
>> int main(void) { for (unsigned int k = 0; k != 1; k += 2){} return 0; }
>> void hello(void) { printf("Hello, World!\n"); }
>> term% clang -O1 -Wall -Werror -pedantic -pedantic-errors -std=c23 -o what what.c
>> term% ./what
>> Hello, World!
>> term% 
>> ```
>
>That's an example of something more specific.  N3220 6.8.6.1p4
>gives explicit permission for an implementation to "assume" that
>certain iteration statements will terminate.  (I've said before
>that I dislike this rule for several reasons.)

Yup.  This behavior indeed allowed by the standard, but that it
is allowed by the standard is, itself, an indictment of the
standard.

>> It's notable that the quoted text for the ANSI C standard also
>> says that an implementation is free to abort translation if it
>> encounters UB, which I recall was something that was a point of
>> concention in the earlier discussion.  Kuyper posted a link to
>> a defect report that suggested that the compiler had to
>> translate the program if it could prove that (in that case,
>> manifest) UB was never triggered; however, that was from 1994,
>> and not normative anyhow.
>
>C89 and all later editions of the C standard say (in a non-normative
>note) that undefined behavior can include "terminating a
>translation or execution (with the issuance of a diagnostic
>message)".  But almost all undefined behavior occurs at run time.
>That could have been worded more clearly, but my interpretation
>is that an implementation that detects that a source construct
>has undefined behavior can terminate translation only if it can
>prove that it's always executed.  `if (0) 1/0;` does not permit
>terminating translation.

Unfortunately, the standard does not say that in normative text.

>>                            The committee has had ample time to
>> tune up the writing about this in the standard, and has chosen
>> not to: Cox's post is on-point; the current standard is deeply
>> flawed.
>
>How would you suggest fixing it?

Honestly?  I don't think that it can be fixed.  There are too
many competing interests, and C is the language that it is.  I
do not think we're going to get away from that.

That said, a thing that they _could_ do is be more explicit
about when termination is allowed and so forth.  The UB working
group is trying to reign in the undue dominance of UB, and I
give them credit for that; I don't know how far they will get,
though.

In the meanwhile, _most_ programmers should not be writing in C.

	- Dan C.

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


#400354

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2026-07-22 13:26 -0700
Message-ID<113r927$396f7$1@dont-email.me>
In reply to#400346
On 7/21/2026 6:50 PM, Dan Cross wrote:
> #include <stdio.h>
> #include <stdlib.h>
> 
> typedef void (*Function)(void);
> 
> static Function Do;
> 
> static void
> baz(void)
> {
>      printf("baz invoked.\n");
> }
> 
> static void
> bar(void)
> {
>      baz();
> }
> 
> void
> foo(void)
> {
>      Do = bar;
> }
> 
> int
> main(void)
> {
>      Do();
>      return 0;
> }

That should be a seg fault? Anyway:

_______________
#include <stdio.h>
#include <stdlib.h>

typedef void (*Function)(void);

static Function Do = NULL;

static void
baz(void)
{
     printf("baz invoked.\n");
}

static void
bar(void)
{
     baz();
}

void
foo(void)
{
     Do = bar;
}

int
main(void)
{
     foo(); // :^)
     Do();
     return 0;
}
_______________


Better? ;^)

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


#400348

FromJanis Papanagnou <janis_papanagnou+ng@hotmail.com>
Date2026-07-22 07:33 +0200
Message-ID<113pkn9$23t9d$1@dont-email.me>
In reply to#400345
On 2026-07-22 02:26, Keith Thompson wrote:
> Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
>> There was some recent longish thread with discussions addressing
>> Undefined Behavior. I just stumbled across a paper from Russ Cox
>> on that topic with a provoking title. [...]
> 
> For those who don't follow the link, the full title of the paper is
> "C and C++ Prioritize Performance over Correctness".  (Your
> paraphrase could be interpreted as advice, which I'm sure is not
> how you intended it.)

It was actually a (deliberate) "marketing trick" to provoke interest
by reducing the title to an (IMO) yet more aggravating formulation.

Yes, it was not my intention to suggest performance over correctness.
(Would anyone?)

Janis

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


#400349

FromDavid Brown <david.brown@hesbynett.no>
Date2026-07-22 10:41 +0200
Message-ID<113pvnb$2mr56$1@dont-email.me>
In reply to#400348
On 22/07/2026 07:33, Janis Papanagnou wrote:
> On 2026-07-22 02:26, Keith Thompson wrote:
>> Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
>>> There was some recent longish thread with discussions addressing
>>> Undefined Behavior. I just stumbled across a paper from Russ Cox
>>> on that topic with a provoking title. [...]
>>
>> For those who don't follow the link, the full title of the paper is
>> "C and C++ Prioritize Performance over Correctness".  (Your
>> paraphrase could be interpreted as advice, which I'm sure is not
>> how you intended it.)
> 
> It was actually a (deliberate) "marketing trick" to provoke interest
> by reducing the title to an (IMO) yet more aggravating formulation.
> 
> Yes, it was not my intention to suggest performance over correctness.
> (Would anyone?)
> 

Unfortunately, the answer to your final question is yes - and that is 
one of the reasons UB can be a problem.  If by "correctness" you mean 
"code does what it should", people do sometimes release code that they 
know has bugs, but they know that fixing them would slow down the code - 
perhaps it is still good enough for their purposes at the time.

More relevant to this discussion, if by "correct" code you mean code 
that has fully defined or appropriate implementation-defined behaviour 
(most code does not need to be fully portable) according to the C 
standards and/or platform or compiler extended semantics, then it is 
absolutely the case that programmers regularly prioritise performance 
over correctness by relying on UB.  The result is code that works 
efficiently and as intended at the time, using tools tested by the 
developer.  Then the UB bites the next person down the road that uses 
the same code in good faith, but with a different compiler or different 
options.

If the reliance on the UB was unintentional, it's a bug - programmers 
are humans, they don't always know everything, and people make mistakes. 
  But some programmers do so /knowing/ that the code is UB.  Sometimes 
it is even stated in comments.  The most common cases, IME, are reliance 
on two's complement wrapping, and messing with pointer casts to access 
data as different types, possibly with incorrect alignment.


As for the linked paper, I am not particularly impressed by its arguments.

I think it is fair enough to have different opinions about what should 
or should not be UB in language standards - and it is inarguably the 
case that some things that are UB could have defined behaviour at quite 
minor performance costs.  (Note, however, that studies looking at the 
performance cost of disabling certain optimisations - such as 
"-fno-strict-aliasing" or "-fwrapv" - almost invariably use only x86 
targets.  x86 processors are designed to get the best from poorly 
optimised code, because that's what is often run on them, while most 
other processors except compilers to do more of the work.  Compiler 
optimisations often have a much bigger impact on non-x86 targets and on 
processors with smaller relative memory latencies.)

Fundamentally, the idea of "UB" is that it describes code that does not 
make sense, where there is no correct answer or meaningful specification 
of behaviour.  What should it mean to dereference a pointer that does 
not point to a valid object of the type you are using?  What should it 
mean to store a large result in a target type that is too small?  Code 
that does this kind of thing is buggy - it cannot give correct answers. 
Nothing the compiler can do could make the code correct.

The compiler's logic then goes like this:

1. UB is incorrect code.
2. C is a "trust the programmer" language.
3. The compiler assumes the programmer has written correct code.
4. Therefore, the programmer has not written code with UB.
5. Therefore, UB cannot happen.
6. Therefore the compiler can optimise on that assumption, such as by 
skipping some code generation.

The only question is, is it a good idea for the compiler to be allowed 
to make the program "more wrong" ?  I don't think it matters as much as 
people often think.  It's easy to find or create examples where compiler 
optimisations on UB can amplify errors.  Equally, however, you can find 
or create examples where assuming some kind of naïve "obvious" 
implementation of the UB code will also lead to bad results.  Programs 
adding two positive integers are going to expect a positive result - a 
wrapped negative result is going to lead to tears.  You need the same 
kind of care in development and testing no matter how the compiler 
treats its UB - and if you have done that job, these kinds of compiler 
optimisations do not significantly (IMHO) affect the risk of later problems.

The killer point, however, is when you have received some code that you 
can justifiably assume is correct and well tested, but contains reliance 
on how certain types of UB happen to be implemented.  It is not really 
any different than code that makes other undocumented assumptions, such 
as implementation-dependent details, reliance on certain files or OS 
features, timing requirements, etc.  And compiling with "-fwrapv 
-fno-strict-aliasing" (if you are using a compiler that supports such 
features) will mitigate the most common cases of reliance on UB.


As for the paper itself, I have a few points.

It follows the time-worn path of complaining that "modern" compilers 
have distorted the "original" idea of UB and abuse it for optimisation 
in ways that are dangerous to the uninitiated.  First, optimisation 
using UB is not new - I first used a compiler that assumed integer 
overflow does not wrap over thirty years ago.  Second, compilers already 
default to "-O0" - if you know so little about your tools that you can't 
enable warnings, you won't have optimisation either.  Third, 
improvements in compiler optimisation have gone hand-in-hand with 
improvements in compiler static error checking.  Using "-Wall" along 
with optimisation will eliminate the solid majority of the risks and 
worries of the author.  Fourth, the development of "sanitizers" not only 
allows far more UB to be found during testing, but it allows far more 
bugs to be found than would be possible if the mistakes were /not/ UB - 
"-fsanitize=signed-integer-overflow" catches overflow bugs precisely 
because it is UB in C, whereas if it were defines as wrapping then the 
mistake in the programmer's code would be correct as far as the language 
is concerned.

Compilers are, of course, not perfect.  But they are usually pretty 
good.  Most of the paper could be scraped and replaced with the advice 
of always using "-Wall", possibly with "-Wextra" and/or fine-tuning of 
other warning flags, regardless of optimisation.  And make use of 
sanitizers while testing.  And always test with solid optimisations 
enabled (like "-O2"), though lower optimisations can be handy for 
fault-finding and debugging some aspects of code.

It repeats the myths about signed integer overflow being UB because some 
computers have different representations of signed integers - C uses 
implementation-defined behaviour to handle implementation differences, 
and only resorts to UB when there is no sensible definition of "correct" 
behaviour, or where implementation-defined behaviour could have 
significant overhead costs.

Both C++ (from C++20, IIRC) and C (from C23) allow only two's complement 
signed integer representations.  Both committees made it clear that 
signed arithmetic overflow is still UB, because it does not lead to a 
sensible answer and allows optimisations and additional error checking. 
It is not hard to get wrapping behaviour if you want it (using 
conversions to and from unsigned types), and C23 introduced standardised 
checked arithmetic functions.


As for infinite loops, loops with a constant controlling expression 
(like "for (;;)" ) are exempt from the "assumed to terminate" clause in 
C.  I don't know if the example given was a bug in Clang or if it used 
C++ and C++ has different rules here.

And in the next example, merging two loops into one, the merge won't 
introduce new bugs or race conditions - if another thread is using 
"count2", then there needs to be some kind of coordination (like 
atomics), and then the loops could not be merged anyway.  I am not 
convinced that allowing the compiler to assume termination of certain 
types of loop is a particularly useful feature - it seems to me to be an 
added complication with very few potential benefits.  But I can't see it 
being a problem for sensible working code either.

Don't dereference null pointers.  It's a bad idea.

Read the specifications of the functions you want to use.  std::sort 
requires a comparison function with a strict weak ordering - give it 
something else, and it's a user bug.  Perhaps std::sort could have been 
specified in a nicer way, but that is hardly a compiler problem.








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


#400358

FromBGB <cr88192@gmail.com>
Date2026-07-22 18:08 -0500
Message-ID<113rinb$3c4f8$2@dont-email.me>
In reply to#400349
On 7/22/2026 3:41 AM, David Brown wrote:
> On 22/07/2026 07:33, Janis Papanagnou wrote:
>> On 2026-07-22 02:26, Keith Thompson wrote:
>>> Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
>>>> There was some recent longish thread with discussions addressing
>>>> Undefined Behavior. I just stumbled across a paper from Russ Cox
>>>> on that topic with a provoking title. [...]
>>>
>>> For those who don't follow the link, the full title of the paper is
>>> "C and C++ Prioritize Performance over Correctness".  (Your
>>> paraphrase could be interpreted as advice, which I'm sure is not
>>> how you intended it.)
>>
>> It was actually a (deliberate) "marketing trick" to provoke interest
>> by reducing the title to an (IMO) yet more aggravating formulation.
>>
>> Yes, it was not my intention to suggest performance over correctness.
>> (Would anyone?)
>>
> 
> Unfortunately, the answer to your final question is yes - and that is 
> one of the reasons UB can be a problem.  If by "correctness" you mean 
> "code does what it should", people do sometimes release code that they 
> know has bugs, but they know that fixing them would slow down the code - 
> perhaps it is still good enough for their purposes at the time.
> 

Or, the cliche: "It's not a bug, it's a feature..."


> More relevant to this discussion, if by "correct" code you mean code 
> that has fully defined or appropriate implementation-defined behaviour 
> (most code does not need to be fully portable) according to the C 
> standards and/or platform or compiler extended semantics, then it is 
> absolutely the case that programmers regularly prioritise performance 
> over correctness by relying on UB.  The result is code that works 
> efficiently and as intended at the time, using tools tested by the 
> developer.  Then the UB bites the next person down the road that uses 
> the same code in good faith, but with a different compiler or different 
> options.
> 


Well, or for example, this pile of wonk:

#define gfxedit_getu16(ptr)       (*(vol_u16p)(ptr))
#define gfxedit_getu32(ptr)       (*(vol_u32p)(ptr))
#define gfxedit_getu64(ptr)       (*(vol_u64p)(ptr))
#define gfxedit_setu16(ptr,val)   (*(vol_u16p)(ptr)=(val))
#define gfxedit_setu32(ptr,val)   (*(vol_u32p)(ptr)=(val))
#define gfxedit_setu64(ptr,val)   (*(vol_u64p)(ptr)=(val))

Insert other versions for different platform constraints.

But, say:
   u64 gfxedit_getu64(void *ptr)
     { u64 v; memcpy(&v, ptr, 8); return(v); }
Being also possible, but a significant performance penalty on some targets.

The situation is potentially much worse for big endian machines, but 
these are rare at this point.

Say:
   u16 gfxedit_getu16(void *ptr)
     { u16 v; v=((byte *)ptr)[0]|
         (((u16)((byte *)ptr)[1]))<<8); return(v); }
   u32 gfxedit_getu32(void *ptr)
     { u32 v; v=gfxedit_getu16(ptr)|
         (((u32)gfxedit_getu16(((byte *)ptr)+2))<<16); return(v); }
   u64 gfxedit_getu64(void *ptr)
     { u64 v; v=gfxedit_getu32(ptr)|
         (((u64)gfxedit_getu32(((byte *)ptr)+4))<<32); return(v); }

Though, for BE machines, one wouldn't want to overuse these.

...


And, the function:

byte *gfxedit_memlzcpyf(byte *dst, byte *src, int len)
{
   byte *cs, *ct, *cte;
   u64 v0, v1;
   int d;
   int i;

   d=dst-src;

   if(d>len)
   {
     cs=src; ct=dst; cte=dst+len;
     v0=gfxedit_getu64(cs);  v1=gfxedit_getu64(cs+8);
     gfxedit_setu64(ct, v0);  gfxedit_setu64(ct+8, v1);
     cs+=16; ct+=16;
     if(ct<cte)
     {
       v0=gfxedit_getu64(cs);  v1=gfxedit_getu64(cs+8);
       gfxedit_setu64(ct, v0);  gfxedit_setu64(ct+8, v1);
       cs+=16; ct+=16;
       if(ct<cte)
       {
         v0=gfxedit_getu64(cs); v1=gfxedit_getu64(cs+8);
         gfxedit_setu64(ct, v0); gfxedit_setu64(ct+8, v1);
         cs+=16; ct+=16;
         while(ct<cte)
         {
           v0=gfxedit_getu64(cs); v1=gfxedit_getu64(cs+8);
           gfxedit_setu64(ct, v0); gfxedit_setu64(ct+8, v1);
           cs+=16; ct+=16;
         }
       }
     }
     return(cte);
   }
   if(d<=8)
   {
     if(d==1)
     {
       v0=*(byte *)src; v0|=(v0<<8); v0|=(v0<<16); v0|=(v0<<32);
       ct=dst; cte=dst+len;
       while(ct<cte)
         { gfxedit_setu64(ct, v0); gfxedit_setu64(ct+8, v0); ct+=16; }
       return(cte);
     }
     if(d==2)
     {
       v0=gfxedit_getu16(src); v0|=(v0<<16); v0|=(v0<<32);
       ct=dst; cte=dst+len;
       while(ct<cte)
         { gfxedit_setu64(ct, v0); gfxedit_setu64(ct+8, v0); ct+=16; }
       return(cte);
     }
     if(d==4)
     {
       v0=gfxedit_getu32(src); v0|=(v0<<32);
       ct=dst; cte=dst+len;
       while(ct<cte)
         { gfxedit_setu64(ct, v0); gfxedit_setu64(ct+8, v0); ct+=16; }
       return(cte);
     }
     if(d==8)
     {
       v0=gfxedit_getu64(src);
       ct=dst; cte=dst+len;
       while(ct<cte)
         { gfxedit_setu64(ct, v0); gfxedit_setu64(ct+8, v0); ct+=16; }
       return(cte);
     }

     if(d<0)
     {
       cs=src; ct=dst; cte=dst+len;
       while(ct<cte)
       {
         v0=gfxedit_getu64(cs); v1=gfxedit_getu64(cs+8);
         gfxedit_setu64(ct, v0); gfxedit_setu64(ct+8, v1);
         cs+=16; ct+=16;
       }
       return(cte);
     }

     if(d==3)
     {
       v0=gfxedit_getu32(src); v0=v0<<40; v0=(v0>>16)|(v0>>40);
       ct=dst; cte=dst+len;
       while(ct<cte)
       {
         gfxedit_setu64(ct+ 0, v0);
         gfxedit_setu64(ct+ 6, v0);
         gfxedit_setu64(ct+12, v0);
         ct+=18;
       }
       return(cte);
     }
     if(d==5)
     {
       v0=gfxedit_getu64(src);
       ct=dst; cte=dst+len;
       while(ct<cte)
         { gfxedit_setu64(ct, v0); ct+=5; }
       return(cte);
     }
     if(d==7)
     {
       v0=gfxedit_getu64(src);
       ct=dst; cte=dst+len;
       while(ct<cte)
         { gfxedit_setu64(ct, v0); ct+=7; }
       return(cte);
     }
     cs=src; ct=dst; cte=dst+len;
     while(ct<cte)
       { *ct++=*cs++; }
     return(cte);
   }
   if(d>=16)
   {
     cs=src; ct=dst; cte=dst+len;
     while(ct<cte)
     {
       v0=gfxedit_getu64(cs); v1=gfxedit_getu64(cs+8);
       gfxedit_setu64(ct, v0); gfxedit_setu64(ct+8, v1);
       cs+=16; ct+=16;
     }
     return(cte);
   }
   else
   {
     cs=src; ct=dst; cte=dst+len;
     while(ct<cte)
       { v0=gfxedit_getu64(cs); gfxedit_setu64(ct, v0); cs+=8; ct+=8; }
     return(cte);
   }
}


Where one might ask, why not just:
byte *gfxedit_memlzcpyf(byte *dst, byte *src, int len)
{
   int i, d;
   d=dst-src;
   if(d>len)
     { memcpy(dst, src, len); return(dst+len); }
   if(d<0)
     { memmove(dst, src, len); return(dst+len); }
   if(d==1)
     { memset(dst, *src, len); return(dst+len); }
   for(i=0; i<len; i++)
     dst[i]=src[i];
   return(dst+len);
}

But, on the relevant implementation, trying to do the latter being 
around an order of magnitude slower...

Note: Not on my target... Where I had added _memlzcpyf() as an extension 
to the C library to avoid having to endlessly re-implement this stuff. 
But, for other targets, it is still necessary.

Where, the 'f' variant is basically the variant that prioritizes speed 
on the allowance that it may copy a little extra.


Well, except on SiFive chips where this in not the fastest option.

The fastest case for a SiFive style CPU being or similar, say:
byte *gfxedit_memlzcpyf(byte *dst, byte *src, int len)
{
   byte *cs, *ct, *cte;
   int i, d;
   cs=src; ct=dst; cte=dst+len;
   while(ct<cte)
     { *ct++=*cs++; }
   return(cte);
}

But, for the original example, this works better on a CPU with higher 
instruction latency, but the ability to use misaligned loads and stores 
with zero added cost (whereas, the SiFive chips have lower 
per-instruction latency but a very steep cost for misaligned memory 
access; basically in the form of hidden trap-and-emulate).

Where, say, both CPU's can run RISc-V code, but have significant 
differences in performance characteristics...

One might also want to use the latter naive byte copy for big endian 
RISC machines (like on PowerPC or similar), ...

So, it can all turn into a big mess of cruft and ifdef's.


And, No:
   You can't just use memmove() here...

In this case the typical repeating bytes on self-overlap behavior being 
required for correct operation.


But, while small and elegant and portable, the above version would be 
undesirable due to being around 10x slower.

One could try to detect alignment and then have separate aligned vs 
unaligned loops, but in the use-case it gains very little and may end up 
slower than always assuming misaligned (where it is a sort of chaos 
where most of the copies are both misaligned and fairly short).



> If the reliance on the UB was unintentional, it's a bug - programmers 
> are humans, they don't always know everything, and people make mistakes. 
>   But some programmers do so /knowing/ that the code is UB.  Sometimes 
> it is even stated in comments.  The most common cases, IME, are reliance 
> on two's complement wrapping, and messing with pointer casts to access 
> data as different types, possibly with incorrect alignment.
> 
> 
> As for the linked paper, I am not particularly impressed by its arguments.
> 
> I think it is fair enough to have different opinions about what should 
> or should not be UB in language standards - and it is inarguably the 
> case that some things that are UB could have defined behaviour at quite 
> minor performance costs.  (Note, however, that studies looking at the 
> performance cost of disabling certain optimisations - such as "-fno- 
> strict-aliasing" or "-fwrapv" - almost invariably use only x86 targets.  
> x86 processors are designed to get the best from poorly optimised code, 
> because that's what is often run on them, while most other processors 
> except compilers to do more of the work.  Compiler optimisations often 
> have a much bigger impact on non-x86 targets and on processors with 
> smaller relative memory latencies.)
> 

The idea is that compilers should still try to produce efficient code 
even with these semantic limitations.


> Fundamentally, the idea of "UB" is that it describes code that does not 
> make sense, where there is no correct answer or meaningful specification 
> of behaviour.  What should it mean to dereference a pointer that does 
> not point to a valid object of the type you are using?  What should it 
> mean to store a large result in a target type that is too small?  Code 
> that does this kind of thing is buggy - it cannot give correct answers. 
> Nothing the compiler can do could make the code correct.
> 
> The compiler's logic then goes like this:
> 
> 1. UB is incorrect code.
> 2. C is a "trust the programmer" language.
> 3. The compiler assumes the programmer has written correct code.
> 4. Therefore, the programmer has not written code with UB.
> 5. Therefore, UB cannot happen.
> 6. Therefore the compiler can optimise on that assumption, such as by 
> skipping some code generation.
> 
> The only question is, is it a good idea for the compiler to be allowed 
> to make the program "more wrong" ?  I don't think it matters as much as 
> people often think.  It's easy to find or create examples where compiler 
> optimisations on UB can amplify errors.  Equally, however, you can find 
> or create examples where assuming some kind of naïve "obvious" 
> implementation of the UB code will also lead to bad results.  Programs 
> adding two positive integers are going to expect a positive result - a 
> wrapped negative result is going to lead to tears.  You need the same 
> kind of care in development and testing no matter how the compiler 
> treats its UB - and if you have done that job, these kinds of compiler 
> optimisations do not significantly (IMHO) affect the risk of later 
> problems.
> 
> The killer point, however, is when you have received some code that you 
> can justifiably assume is correct and well tested, but contains reliance 
> on how certain types of UB happen to be implemented.  It is not really 
> any different than code that makes other undocumented assumptions, such 
> as implementation-dependent details, reliance on certain files or OS 
> features, timing requirements, etc.  And compiling with "-fwrapv -fno- 
> strict-aliasing" (if you are using a compiler that supports such 
> features) will mitigate the most common cases of reliance on UB.
> 

In some cases, it makes sense to assume that some things formally 
considered UB would be better considered as Implementation Defined.

In practice, it likely wouldn't make that big of a difference; since 
many cases the compiler still treats these cases is implementation 
defined rather than true UB.


In this case, this leaves "true UB" as mostly cases where no sensible or 
consistent behavior can be expected even within a given machine, say:
   reliance on the values of uninitialized local variables;
   going out of bounds on a conventional array (*1).

*1: I consider out-of-bounds within an array inside a struct to be a 
partial exception, as one can reasonably assume that going OOB would 
access other members within the same struct.

But, the relative ordering and layout of stack and global variables I 
considered to be outside the scope of where valid assumptions can be 
made in C.


However, such assumptions could be made for assembler...

Granted, in premise one could do, say:
   extern u64 arr1[4];
   extern u64 arr2[4];

   __asm {
     .section .data
     .global arr1
     .global arr2
     arr1:
       .quad 0
       .quad 0
       .quad 0
       .quad 0
     arr2:
       .quad 0
       .quad 0
       .quad 0
       .quad 0
   };

And, arguably in this case one can argue that it may be valid to assume 
that arr1 overflows into arr2.

But, then again, one also can't rely on the portability of __asm or 
__asm__ blocks between targets. So, like with the structs, this would 
exist more as a partial exception.

This example being partly N/A for GCC or similar, which uses a different 
syntax for ASM blocks (well, and some compilers, like 64-bit MSVC, 
having dropped support for inline ASM).


But, I had seen non-zero code which had relied on the assumption of 
overflows carrying over consistently between global arrays.

In my compiler, such assumptions are not safe to be made, as the 
compiler likes to shuffle the declarations around. Partly balancing 
randomization and efficiency; as it can be more efficient to arrange 
variables by usage frequency, and functions by a combination of 
frequency and proximity. Say, ideally keeping commonly called functions 
closer together, and if possible also clustering callers and callees 
closer together. Even in the absence of profiler feedback, it tends to 
make it such that the "cold path" is less likely to be part of the core 
working set (and reducing the TLB miss frequency).


Did run into a little bit of a hassle recently that my compilers' output 
tends to have a section alignment smaller than the page alignment, which 
turned into a bit of pain trying to set up page access permissions for 
the kernel binary (moving away from just setting the whole thing as RWX).

Ended up adding a few special case flags to the implementation of the 
"mprotect" functionality:
   INNER: Only applies to completely covered pages,
     ignores partial pages.
     Default: covers all pages in range.
   ALLOW: Only allows new access, does not remove access.
   DENY: Only removes access.
     Default: New permissions fully replace old permissions.

These allowed dealing better with the partial page scenarios.
   Can initially set the whole image READ|NOUSER;
   Then use ALLOW to add WRITE/EXEC/USER to the relevant sections.
     Maybe questionable, but there does exist a R|X|USER section.
     Mostly has stuff for Syscalls and COM.
       It is likely this part could be migrated into Userland.
       Mostly it is a vestige of an earlier developmental stage.


> 
> As for the paper itself, I have a few points.
> 
> It follows the time-worn path of complaining that "modern" compilers 
> have distorted the "original" idea of UB and abuse it for optimisation 
> in ways that are dangerous to the uninitiated.  First, optimisation 
> using UB is not new - I first used a compiler that assumed integer 
> overflow does not wrap over thirty years ago.  Second, compilers already 
> default to "-O0" - if you know so little about your tools that you can't 
> enable warnings, you won't have optimisation either.  Third, 
> improvements in compiler optimisation have gone hand-in-hand with 
> improvements in compiler static error checking.  Using "-Wall" along 
> with optimisation will eliminate the solid majority of the risks and 
> worries of the author.  Fourth, the development of "sanitizers" not only 
> allows far more UB to be found during testing, but it allows far more 
> bugs to be found than would be possible if the mistakes were /not/ UB - 
> "-fsanitize=signed-integer-overflow" catches overflow bugs precisely 
> because it is UB in C, whereas if it were defines as wrapping then the 
> mistake in the programmer's code would be correct as far as the language 
> is concerned.
> 

For keeping old code working, it makes sense to assume wrapping.

But, maybe it could make sense to have a semantic distinction for cases 
where wrapping is assumed vs where it is likely unintentional.

My proposal, if any, would be, say:
   If "signed" is used explicitly, it means wrap-on-overflow is expected.

So, say:
   int i;
   signed int v;
If 'i' overflows, one can question whether or not it was intended; but 
if 'v' overflows, assume it is intentional (as with 'unsigned').

This being in part because an explicit "signed" keyword is uncommon to 
be used with normal counting/index type variables.



> Compilers are, of course, not perfect.  But they are usually pretty 
> good.  Most of the paper could be scraped and replaced with the advice 
> of always using "-Wall", possibly with "-Wextra" and/or fine-tuning of 
> other warning flags, regardless of optimisation.  And make use of 
> sanitizers while testing.  And always test with solid optimisations 
> enabled (like "-O2"), though lower optimisations can be handy for fault- 
> finding and debugging some aspects of code.
> 
> It repeats the myths about signed integer overflow being UB because some 
> computers have different representations of signed integers - C uses 
> implementation-defined behaviour to handle implementation differences, 
> and only resorts to UB when there is no sensible definition of "correct" 
> behaviour, or where implementation-defined behaviour could have 
> significant overhead costs.
> 
> Both C++ (from C++20, IIRC) and C (from C23) allow only two's complement 
> signed integer representations.  Both committees made it clear that 
> signed arithmetic overflow is still UB, because it does not lead to a 
> sensible answer and allows optimisations and additional error checking. 
> It is not hard to get wrapping behaviour if you want it (using 
> conversions to and from unsigned types), and C23 introduced standardised 
> checked arithmetic functions.
> 
> 
> As for infinite loops, loops with a constant controlling expression 
> (like "for (;;)" ) are exempt from the "assumed to terminate" clause in 
> C.  I don't know if the example given was a bug in Clang or if it used 
> C++ and C++ has different rules here.
> 
> And in the next example, merging two loops into one, the merge won't 
> introduce new bugs or race conditions - if another thread is using 
> "count2", then there needs to be some kind of coordination (like 
> atomics), and then the loops could not be merged anyway.  I am not 
> convinced that allowing the compiler to assume termination of certain 
> types of loop is a particularly useful feature - it seems to me to be an 
> added complication with very few potential benefits.  But I can't see it 
> being a problem for sensible working code either.
> 
> Don't dereference null pointers.  It's a bad idea.
> 

Dereferencing NULL is one of those cases where the most sensible option 
is to treat it as a fault...

Most sensible option is to assume that trying to dereference NULL is 
unintentional (given the main purpose of NULL being as a "this object 
doesn't exist" pointer).

But:
Assuming it doesn't happen and then removing the offending code path 
entirely is also bad IMO. However, turning the code-path into a break 
instruction or similar (following any other externally visible side 
effects) would still likely be acceptable IMO (or, at least, less bad in 
this case than just continuing down the other path as if nothing had 
ever happened).



> Read the specifications of the functions you want to use.  std::sort 
> requires a comparison function with a strict weak ordering - give it 
> something else, and it's a user bug.  Perhaps std::sort could have been 
> specified in a nicer way, but that is hardly a compiler problem.
> 

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


#400364

FromDavid Brown <david.brown@hesbynett.no>
Date2026-07-23 10:31 +0200
Message-ID<113sjg8$3k0q6$1@dont-email.me>
In reply to#400358
On 23/07/2026 01:08, BGB wrote:
> On 7/22/2026 3:41 AM, David Brown wrote:
>> On 22/07/2026 07:33, Janis Papanagnou wrote:
>>> On 2026-07-22 02:26, Keith Thompson wrote:
>>>> Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
>>>>> There was some recent longish thread with discussions addressing
>>>>> Undefined Behavior. I just stumbled across a paper from Russ Cox
>>>>> on that topic with a provoking title. [...]
>>>>
>>>> For those who don't follow the link, the full title of the paper is
>>>> "C and C++ Prioritize Performance over Correctness".  (Your
>>>> paraphrase could be interpreted as advice, which I'm sure is not
>>>> how you intended it.)
>>>
>>> It was actually a (deliberate) "marketing trick" to provoke interest
>>> by reducing the title to an (IMO) yet more aggravating formulation.
>>>
>>> Yes, it was not my intention to suggest performance over correctness.
>>> (Would anyone?)
>>>
>>
>> Unfortunately, the answer to your final question is yes - and that is 
>> one of the reasons UB can be a problem.  If by "correctness" you mean 
>> "code does what it should", people do sometimes release code that they 
>> know has bugs, but they know that fixing them would slow down the code 
>> - perhaps it is still good enough for their purposes at the time.
>>
> 
> Or, the cliche: "It's not a bug, it's a feature..."
> 

Possibly.

But it is always important to remember that different types of software 
require different levels of quality control - it can be acceptable to 
have known bugs ("undocumented features" or "undocumented limitations") 
in some software.  If video games were coded with the same level of care 
used for jet engine controllers, they would never make it to market.

> 
>> More relevant to this discussion, if by "correct" code you mean code 
>> that has fully defined or appropriate implementation-defined behaviour 
>> (most code does not need to be fully portable) according to the C 
>> standards and/or platform or compiler extended semantics, then it is 
>> absolutely the case that programmers regularly prioritise performance 
>> over correctness by relying on UB.  The result is code that works 
>> efficiently and as intended at the time, using tools tested by the 
>> developer.  Then the UB bites the next person down the road that uses 
>> the same code in good faith, but with a different compiler or 
>> different options.
>>
> 
> 
> Well, or for example, this pile of wonk:
> 
> #define gfxedit_getu16(ptr)       (*(vol_u16p)(ptr))
> #define gfxedit_getu32(ptr)       (*(vol_u32p)(ptr))
> #define gfxedit_getu64(ptr)       (*(vol_u64p)(ptr))
> #define gfxedit_setu16(ptr,val)   (*(vol_u16p)(ptr)=(val))
> #define gfxedit_setu32(ptr,val)   (*(vol_u32p)(ptr)=(val))
> #define gfxedit_setu64(ptr,val)   (*(vol_u64p)(ptr)=(val))
> 
> Insert other versions for different platform constraints.

While details of volatile accesses are implementation-dependent, they 
can be a successful way of accessing the underlying memory for data. 
It's easy to get things wrong, however, if you are not consistent about 
it.  And too much use can lead to inefficiencies as well.

> 
> But, say:
>    u64 gfxedit_getu64(void *ptr)
>      { u64 v; memcpy(&v, ptr, 8); return(v); }
> Being also possible, but a significant performance penalty on some targets.
> 

That's the challenge.  memcpy() is often a good, safe and correct way to 
access data as though it were a different type, but not all compilers 
optimise it well in such cases.  Making code that is correct on a range 
of implementations, and also efficient on a range of implementations, is 
the hard part.  So sometimes people end up with code that is efficienct 
on the implementations they use, works on those, but is reliant on UB 
and fails on other implementations.

> The situation is potentially much worse for big endian machines, but 
> these are rare at this point.
> 
> Say:
>    u16 gfxedit_getu16(void *ptr)
>      { u16 v; v=((byte *)ptr)[0]|
>          (((u16)((byte *)ptr)[1]))<<8); return(v); }
>    u32 gfxedit_getu32(void *ptr)
>      { u32 v; v=gfxedit_getu16(ptr)|
>          (((u32)gfxedit_getu16(((byte *)ptr)+2))<<16); return(v); }
>    u64 gfxedit_getu64(void *ptr)
>      { u64 v; v=gfxedit_getu32(ptr)|
>          (((u64)gfxedit_getu32(((byte *)ptr)+4))<<32); return(v); }
> 
> Though, for BE machines, one wouldn't want to overuse these.
> 

On good modern compilers, that sort of thing is usually fine, and you 
would expect it to reduce to a single "load 64-bit with endian swap" 
instruction or minimal similar sequence.

As I see it, the main problem of UB and compilers is /not/ as commonly 
believed, overly-enthusiastic compilers that optimise on assumptions 
about UB.  The problem is poorer or older compilers that don't optimise 
the correct code well, forcing people who need efficient results to 
spend a lot of effort finding alternative solutions that might be 
reliant on UB.  It also doesn't help that some developers don't enable 
optimisation or otherwise fail to use their tools well.


<snip code>

> 
> But, on the relevant implementation, trying to do the latter being 
> around an order of magnitude slower...

It sounds like it might make more sense to write improved memcpy, memove 
and memset implementations for the implementation in question!

> 
> So, it can all turn into a big mess of cruft and ifdef's.
> 

Maximum efficiency is /always/ going to be implementation and target 
dependent.  It is fine, for low-level functions where the speed matters, 
to have a variety of implementations tuned to different targets, with 
fall-back to something that is correct portable code.  The use of 
#ifdef's (or separate files) means you can also happily use 
compiler-specific extensions, pragmas, attributes, builtins, etc., or 
even inline assembly.

>> The killer point, however, is when you have received some code that 
>> you can justifiably assume is correct and well tested, but contains 
>> reliance on how certain types of UB happen to be implemented.  It is 
>> not really any different than code that makes other undocumented 
>> assumptions, such as implementation-dependent details, reliance on 
>> certain files or OS features, timing requirements, etc.  And compiling 
>> with "-fwrapv -fno- strict-aliasing" (if you are using a compiler that 
>> supports such features) will mitigate the most common cases of 
>> reliance on UB.
>>
> 
> In some cases, it makes sense to assume that some things formally 
> considered UB would be better considered as Implementation Defined.

No, never.  You might want that to be the case (and I am sure we all 
have our personal favourite UB's from the C standards that we would 
rather have as IB, or unspecified, or the up-coming "erroneous 
behaviour" - though we would not agree entirely on which UB's).  But you 
can't just say "I think left-shift of negative numbers should be IB" and 
assume it to be the case!

> 
> In practice, it likely wouldn't make that big of a difference; since 
> many cases the compiler still treats these cases is implementation 
> defined rather than true UB.
> 

Particular implementations can, of course, document the way a particular 
type of UB is implemented - then when you are using that compiler, you 
can rely on that behaviour.

Relying on undocumented treatment of UB is where you get in trouble. 
The code might work as you want with this version of the compiler, and 
fail with the next version.

> 
> But, I had seen non-zero code which had relied on the assumption of 
> overflows carrying over consistently between global arrays.
> 

Relying on the details of how generated assembly is organised is a 
high-risk game.  I have had occasions when I needed to do so, but it's 
tightly tied to exact tool versions and flags, and needs checking for 
every run of the build.

> 
>>
>> As for the paper itself, I have a few points.
>>
>> It follows the time-worn path of complaining that "modern" compilers 
>> have distorted the "original" idea of UB and abuse it for optimisation 
>> in ways that are dangerous to the uninitiated.  First, optimisation 
>> using UB is not new - I first used a compiler that assumed integer 
>> overflow does not wrap over thirty years ago.  Second, compilers 
>> already default to "-O0" - if you know so little about your tools that 
>> you can't enable warnings, you won't have optimisation either.  Third, 
>> improvements in compiler optimisation have gone hand-in-hand with 
>> improvements in compiler static error checking.  Using "-Wall" along 
>> with optimisation will eliminate the solid majority of the risks and 
>> worries of the author.  Fourth, the development of "sanitizers" not 
>> only allows far more UB to be found during testing, but it allows far 
>> more bugs to be found than would be possible if the mistakes were / 
>> not/ UB - "-fsanitize=signed-integer-overflow" catches overflow bugs 
>> precisely because it is UB in C, whereas if it were defines as 
>> wrapping then the mistake in the programmer's code would be correct as 
>> far as the language is concerned.
>>
> 
> For keeping old code working, it makes sense to assume wrapping.

To be clear - you mean that if you don't know the old code, it makes 
sense to assume the code might rely on wrapping behaviour, and use 
appropriate compiler flags (or add appropriate pragmas) ?

> 
> But, maybe it could make sense to have a semantic distinction for cases 
> where wrapping is assumed vs where it is likely unintentional.
> 
> My proposal, if any, would be, say:
>    If "signed" is used explicitly, it means wrap-on-overflow is expected.

That makes no sense at all.

> 
> So, say:
>    int i;
>    signed int v;
> If 'i' overflows, one can question whether or not it was intended; but 
> if 'v' overflows, assume it is intentional (as with 'unsigned').

You can't just invent a personal convention like that - at least, not if 
you ever use other people's code or compilers written by someone else. 
You can't change the meaning of existing code.

If C were ever to have support for something akin to that, I would 
expect to see new names involved.  It would be "_Wrapping int v;", or 
types "int_wrapping32_t" in <stdint.h>.

More likely, functions like "wrapping_add" could be added to <stdckdint.h>.

> 
> This being in part because an explicit "signed" keyword is uncommon to 
> be used with normal counting/index type variables.
> 

Some people use it - and they do not do so with the expectation of 
different semantics than when it is omitted.  Some people write "signed" 
rather than "int" for declarations.

>>
>> Don't dereference null pointers.  It's a bad idea.
>>
> 
> Dereferencing NULL is one of those cases where the most sensible option 
> is to treat it as a fault...

It's a bug.

> 
> Most sensible option is to assume that trying to dereference NULL is 
> unintentional (given the main purpose of NULL being as a "this object 
> doesn't exist" pointer).
> 

Yes.

There is the exception that on some hardware, 0 is a valid memory 
address and you might want to access it.  On microcontrollers, it is not 
uncommon for code flash to start there, so something like an integrity 
check of the program would have to read that address.  Then you are 
dereferencing a pointer that happens to have value 0, rather than a null 
pointer.

> But:
> Assuming it doesn't happen and then removing the offending code path 
> entirely is also bad IMO. However, turning the code-path into a break 
> instruction or similar (following any other externally visible side 
> effects) would still likely be acceptable IMO (or, at least, less bad in 
> this case than just continuing down the other path as if nothing had 
> ever happened).
> 

You are thinking of code like :

	int x = *p;
	if (!p) return someone_made_a_mistake;
	...

Some compilers will skip the check here, because they assume the 
hardware / OS will have caught the attempt to access address 0.  That is 
fair enough - /if/ the target is guaranteed to have such a hardware 
catch.  If it is not guaranteed, then the check can't be skipped.  Even 
better, of course, would be a compiler warning that the programmer is 
doing something silly - whether or not the check is skipped.

I agree that sometimes a "break" (or "trap", or similar) instruction can 
be a good thing for compilers to generate when they are clearly 
executing undefined behaviour.  But I am not convinced it is always a 
good idea (I would not want it for this case), and it would be hard to 
specify and guarantee the circumstances without it ruining the 
possibility of optimisation from assuming code has defined behaviour.

Compilers with sanitizers do support such traps - gcc with the options 
"-fsanitize-trap=all -fsanitize=null" will trap if the pointer "p" is 
null in this code.

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


#400371

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2026-07-23 14:31 -0700
Message-ID<113u16u$6bo3$1@kst.eternal-september.org>
In reply to#400364
David Brown <david.brown@hesbynett.no> writes:
[...]
> You are thinking of code like :
>
> 	int x = *p;
> 	if (!p) return someone_made_a_mistake;
> 	...
>
> Some compilers will skip the check here, because they assume the
> hardware / OS will have caught the attempt to access address 0.  That
> is fair enough - /if/ the target is guaranteed to have such a hardware
> catch.  If it is not guaranteed, then the check can't be skipped.

Yes, it can.  A conforming compiler can omit the (!p) test because the
behavior is undefined, not (necessarily) because of the behavior of the
target system.

> Even better, of course, would be a compiler warning that the
> programmer is doing something silly - whether or not the check is
> skipped.

Certainly a warning would be nice.  The problem is that unexpected
optimizations in the presence of undefined behavior don't always occur
because the compiler *knows* that the behavior is undefined.

[...]

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */

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


#400372

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2026-07-23 14:48 -0700
Message-ID<113u27c$6bo3$2@kst.eternal-september.org>
In reply to#400371
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
> David Brown <david.brown@hesbynett.no> writes:
> [...]
>> You are thinking of code like :
>>
>> 	int x = *p;
>> 	if (!p) return someone_made_a_mistake;
>> 	...
>>
>> Some compilers will skip the check here, because they assume the
>> hardware / OS will have caught the attempt to access address 0.  That
>> is fair enough - /if/ the target is guaranteed to have such a hardware
>> catch.  If it is not guaranteed, then the check can't be skipped.
>
> Yes, it can.  A conforming compiler can omit the (!p) test because the
> behavior is undefined, not (necessarily) because of the behavior of the
> target system.

Sorry, I was imprecise.

If p is a null pointer, the behavior is undefined.  If p is a
valid non-null pointer, the behavior is well defined, and the
`return someone_made_a_mistake;` statement will be executed.  Since
returning `someone_made_a_mistake` is a valid example of undefined
behavior, a compiler can simplify the code to an unconditional
`return someone_made_a_mistake;`.

It can't just omit checks because the behavior *might* be undefined.

>> Even better, of course, would be a compiler warning that the
>> programmer is doing something silly - whether or not the check is
>> skipped.
>
> Certainly a warning would be nice.  The problem is that unexpected
> optimizations in the presence of undefined behavior don't always occur
> because the compiler *knows* that the behavior is undefined.
>
> [...]

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */

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


#400373

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2026-07-23 15:11 -0700
Message-ID<113u3j5$7cq1$1@kst.eternal-september.org>
In reply to#400372
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>> David Brown <david.brown@hesbynett.no> writes:
>> [...]
>>> You are thinking of code like :
>>>
>>> 	int x = *p;
>>> 	if (!p) return someone_made_a_mistake;
>>> 	...
>>>
>>> Some compilers will skip the check here, because they assume the
>>> hardware / OS will have caught the attempt to access address 0.  That
>>> is fair enough - /if/ the target is guaranteed to have such a hardware
>>> catch.  If it is not guaranteed, then the check can't be skipped.
>>
>> Yes, it can.  A conforming compiler can omit the (!p) test because the
>> behavior is undefined, not (necessarily) because of the behavior of the
>> target system.
>
> Sorry, I was imprecise.

Sorry, I was also *wrong*.

> If p is a null pointer, the behavior is undefined.  If p is a
> valid non-null pointer, the behavior is well defined, and the
> `return someone_made_a_mistake;` statement will be executed.  Since
> returning `someone_made_a_mistake` is a valid example of undefined
> behavior, a compiler can simplify the code to an unconditional
> `return someone_made_a_mistake;`.

Correction: if p is a valid non-null pointer, the behavior is well
defined, and the `return someone_made_a_mistake;` statement will *NOT*
be executed.  A conforming compiler can emit code that does nothing.

For that matter, the behavior is undefined if p is an invalid non-null
pointer, so that dereferencing it has UB.

> It can't just omit checks because the behavior *might* be undefined.
>
>>> Even better, of course, would be a compiler warning that the
>>> programmer is doing something silly - whether or not the check is
>>> skipped.
>>
>> Certainly a warning would be nice.  The problem is that unexpected
>> optimizations in the presence of undefined behavior don't always occur
>> because the compiler *knows* that the behavior is undefined.
>>
>> [...]

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */

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


#400382

FromDavid Brown <david.brown@hesbynett.no>
Date2026-07-24 09:23 +0200
Message-ID<113v3u3$gi3r$1@dont-email.me>
In reply to#400373
On 24/07/2026 00:11, Keith Thompson wrote:
> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>> David Brown <david.brown@hesbynett.no> writes:
>>> [...]
>>>> You are thinking of code like :
>>>>
>>>> 	int x = *p;
>>>> 	if (!p) return someone_made_a_mistake;
>>>> 	...
>>>>
>>>> Some compilers will skip the check here, because they assume the
>>>> hardware / OS will have caught the attempt to access address 0.  That
>>>> is fair enough - /if/ the target is guaranteed to have such a hardware
>>>> catch.  If it is not guaranteed, then the check can't be skipped.
>>>
>>> Yes, it can.  A conforming compiler can omit the (!p) test because the
>>> behavior is undefined, not (necessarily) because of the behavior of the
>>> target system.

See below for more discussion.

In the case of gcc's "-fdelete-null-pointer-checks" flag, the compiler 
documentation says that look-after-you-leap null pointer checks can be 
eliminated because the compiler assumes that any dereferencing of 
address zero results in a trap.  The big fuss when this flag was 
introduced (and enabled by default) in gcc was because the Linux kernel 
contained such mistakes in the code, and by default address 0 was 
accessible without causing a trap.

>>
>> Sorry, I was imprecise.
> 
> Sorry, I was also *wrong*.
> 
>> If p is a null pointer, the behavior is undefined.  If p is a
>> valid non-null pointer, the behavior is well defined, and the
>> `return someone_made_a_mistake;` statement will be executed.  Since
>> returning `someone_made_a_mistake` is a valid example of undefined
>> behavior, a compiler can simplify the code to an unconditional
>> `return someone_made_a_mistake;`.
> 
> Correction: if p is a valid non-null pointer, the behavior is well
> defined, and the `return someone_made_a_mistake;` statement will *NOT*
> be executed.  A conforming compiler can emit code that does nothing.
> 

(Caveat - what I am about to write is the best of my understanding, but 
it might not be correct.  If I am wrong, I am happy to be corrected!)

The trouble with your argument here is that a pointer with value 0 is 
not necessarily a null pointer (and I'm assuming an implementation where 
null pointers have a value 0, not anything weirder than that).

Null pointers are generated from null pointer constants - 0, (void*) 0, 
and nullptr.  If you have a pointer that happens to contain the value 0 
but it did not come from a null pointer constant, it is not a null 
pointer and dereferencing it is not inherently UB.  (Of course it is 
still UB if it does not point to a valid object of appropriate type.)

The evaluation of "!p" is based on a comparison of "p" to the value 0 - 
it will be true if p contains the value 0.  (This point is perhaps the 
weak link in my reasoning - maybe "!p" is only true if "p" is actually a 
null pointer.  However, I am confident that all real implementations, 
where null pointers are value 0, act by comparison of the value.)

As far as I can see, therefore, "p" can be a valid pointer to an object 
of appropriate type, not be a null pointer, and still have value 0 and 
have "!p" evaluate to 1.


> For that matter, the behavior is undefined if p is an invalid non-null
> pointer, so that dereferencing it has UB.
> 

Agreed.

Of course, a compiler can only optimise away UB code if it knows it is 
UB - the compiler usually cannot know that a general pointer is invalid.

>> It can't just omit checks because the behavior *might* be undefined.
>>
>>>> Even better, of course, would be a compiler warning that the
>>>> programmer is doing something silly - whether or not the check is
>>>> skipped.
>>>
>>> Certainly a warning would be nice.  The problem is that unexpected
>>> optimizations in the presence of undefined behavior don't always occur
>>> because the compiler *knows* that the behavior is undefined.
>>>

Yes, indeed.  And compilers are built up with lots of passes and do not 
hold all information throughout the chain (otherwise they would be a lot 
bigger, a lot slower, and use a lot more memory).  Often by the time 
code is eliminated or re-arranged in later passes, the original reason 
is lost.  Older versions of gcc had a warning you could enable to tell 
you when code was eliminated - the warning was removed because it was 
too noisy in the face of more advanced optimisations (like code folding, 
constant propagation, and function cloning), and there was no practical 
reliable way to give just the helpful cases.  We can always wish for 
better warnings, and keep asking for them from our compiler vendors, but 
the compiler writers are unfortunately limited by practical realities.

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


#400383

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2026-07-24 03:14 -0700
Message-ID<113vdth$johs$1@kst.eternal-september.org>
In reply to#400382
David Brown <david.brown@hesbynett.no> writes:
> On 24/07/2026 00:11, Keith Thompson wrote:
>> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>>> David Brown <david.brown@hesbynett.no> writes:
>>>> [...]
>>>>> You are thinking of code like :
>>>>>
>>>>> 	int x = *p;
>>>>> 	if (!p) return someone_made_a_mistake;
>>>>> 	...
>>>>>
>>>>> Some compilers will skip the check here, because they assume the
>>>>> hardware / OS will have caught the attempt to access address 0.  That
>>>>> is fair enough - /if/ the target is guaranteed to have such a hardware
>>>>> catch.  If it is not guaranteed, then the check can't be skipped.
>>>>
>>>> Yes, it can.  A conforming compiler can omit the (!p) test because the
>>>> behavior is undefined, not (necessarily) because of the behavior of the
>>>> target system.
>
> See below for more discussion.
>
> In the case of gcc's "-fdelete-null-pointer-checks" flag, the compiler
> documentation says that look-after-you-leap null pointer checks can be
> eliminated because the compiler assumes that any dereferencing of
> address zero results in a trap.  The big fuss when this flag was
> introduced (and enabled by default) in gcc was because the Linux
> kernel contained such mistakes in the code, and by default address 0
> was accessible without causing a trap.

That's the gcc documentation's rationale for its behavior --
and that's perfectly valid.  My point is that evaluating *p
if p is a null pointer has undefined behavior in the language
(in the abstract machine), and therefore the condition !p
can be true when it's evaluated only if the previous line has
already had undefined behavior.  A conforming C compiler could
implement the optimization (of not generating code for `return
someone_made_a_mistake;) regardless of the target system's actual
behavior on defererencing a null pointer -- even if, for example,
evaluating `*p` on a null pointer always yielded a consistent value
(say, 0 of p is of type int*).

If a null pointer is represented as all-bits-zero and dereferencing
an all-bits-zero pointer is likely to be a sensible thing to do,
then a *useful* compiler is likely -- but a *standard-conforming*
compiler isn't required to do so.

>>> Sorry, I was imprecise.
>> Sorry, I was also *wrong*.
>> 
>>> If p is a null pointer, the behavior is undefined.  If p is a
>>> valid non-null pointer, the behavior is well defined, and the
>>> `return someone_made_a_mistake;` statement will be executed.  Since
>>> returning `someone_made_a_mistake` is a valid example of undefined
>>> behavior, a compiler can simplify the code to an unconditional
>>> `return someone_made_a_mistake;`.
>> Correction: if p is a valid non-null pointer, the behavior is well
>> defined, and the `return someone_made_a_mistake;` statement will *NOT*
>> be executed.  A conforming compiler can emit code that does nothing.
>
> (Caveat - what I am about to write is the best of my understanding,
> but it might not be correct.  If I am wrong, I am happy to be
> corrected!)
>
> The trouble with your argument here is that a pointer with value 0 is
> not necessarily a null pointer (and I'm assuming an implementation
> where null pointers have a value 0, not anything weirder than that).
>
> Null pointers are generated from null pointer constants - 0, (void*)
> 0, and nullptr.  If you have a pointer that happens to contain the
> value 0 but it did not come from a null pointer constant, it is not a
> null pointer and dereferencing it is not inherently UB.  (Of course it
> is still UB if it does not point to a valid object of appropriate
> type.)

So you're restricting the discussion to systems where a null pointer is
represented as all-bits-zero.  I don't think that makes any difference
to the abstract semantics, but I'll accept it.

A null pointer constant, when converted to a pointer type, yields
a null pointer value, so that's *one* way to obtain a null pointer
value -- but it's not the only one.  malloc(SIZE_MAX) or
fopen("", "") will almost certainly return a null pointer value
as well, and that's just as null as one obtained by evaluating
`nullptr` or `(void*)0`.  In particular, `malloc(SIZE_MAX) == nullptr`
will very probably evaluate to 1.

On the other hand, there are issues of "provenance", such that a pointer
value obtained by `memset(ptr_obj, 0, sizeof ptr_obj)` has the same
representation as a null pointer but might not qualify as one in certain
circumstances.  But I don't understand that issue well enough to discuss
it.

> The evaluation of "!p" is based on a comparison of "p" to the value 0
> - it will be true if p contains the value 0.  (This point is perhaps
> the weak link in my reasoning - maybe "!p" is only true if "p" is
> actually a null pointer.  However, I am confident that all real
> implementations, where null pointers are value 0, act by comparison of
> the value.)

The evaluation of `!p` yields 0 if p compares unequal to 0, 1 if
it compares equal to 0.  It's equivalent to `p == 0`.  In that
comparison, the right operand is implicitly converted to a null
pointer of the type of p.  In other words, `!p` means precisely
"the value of p is a null pointer value", or "p is a null pointer".

> As far as I can see, therefore, "p" can be a valid pointer to an
> object of appropriate type, not be a null pointer, and still have
> value 0 and have "!p" evaluate to 1.

Only in the presence of undefined behavior, in which case the value
of "p" can be a lovely shade of blue.

>> For that matter, the behavior is undefined if p is an invalid non-null
>> pointer, so that dereferencing it has UB.
>> 
>
> Agreed.
>
> Of course, a compiler can only optimise away UB code if it knows it is
> UB - the compiler usually cannot know that a general pointer is
> invalid.
>
>>> It can't just omit checks because the behavior *might* be undefined.
>>>
>>>>> Even better, of course, would be a compiler warning that the
>>>>> programmer is doing something silly - whether or not the check is
>>>>> skipped.
>>>>
>>>> Certainly a warning would be nice.  The problem is that unexpected
>>>> optimizations in the presence of undefined behavior don't always occur
>>>> because the compiler *knows* that the behavior is undefined.
>>>>
>
> Yes, indeed.  And compilers are built up with lots of passes and do
> not hold all information throughout the chain (otherwise they would be
> a lot bigger, a lot slower, and use a lot more memory).  Often by the
> time code is eliminated or re-arranged in later passes, the original
> reason is lost.  Older versions of gcc had a warning you could enable
> to tell you when code was eliminated - the warning was removed because
> it was too noisy in the face of more advanced optimisations (like code
> folding, constant propagation, and function cloning), and there was no
> practical reliable way to give just the helpful cases.  We can always
> wish for better warnings, and keep asking for them from our compiler
> vendors, but the compiler writers are unfortunately limited by
> practical realities.

Often the optimizations and other transformations are performed on
intermediate forms that can't easily be described in terms of the
source code.

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */

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


#400390

Fromscott@slp53.sl.home (Scott Lurndal)
Date2026-07-24 14:56 +0000
Message-ID<t2L8S.522644$lkZe.245771@fx14.iad>
In reply to#400382
David Brown <david.brown@hesbynett.no> writes:
>On 24/07/2026 00:11, Keith Thompson wrote:
>> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>>> David Brown <david.brown@hesbynett.no> writes:
>>>> [...]
>>>>> You are thinking of code like :
>>>>>
>>>>> 	int x = *p;
>>>>> 	if (!p) return someone_made_a_mistake;
>>>>> 	...
>>>>>
>>>>> Some compilers will skip the check here, because they assume the
>>>>> hardware / OS will have caught the attempt to access address 0.  That
>>>>> is fair enough - /if/ the target is guaranteed to have such a hardware
>>>>> catch.  If it is not guaranteed, then the check can't be skipped.
>>>>
>>>> Yes, it can.  A conforming compiler can omit the (!p) test because the
>>>> behavior is undefined, not (necessarily) because of the behavior of the
>>>> target system.
>
>See below for more discussion.
>
>In the case of gcc's "-fdelete-null-pointer-checks" flag, the compiler 
>documentation says that look-after-you-leap null pointer checks can be 
>eliminated because the compiler assumes that any dereferencing of 
>address zero results in a trap.  The big fuss when this flag was 
>introduced (and enabled by default) in gcc was because the Linux kernel 
>contained such mistakes in the code, and by default address 0 was 
>accessible without causing a trap.

It's worth pointing out one of the big differences between System V
and BSD unix operating systems - where the latter would map a read-only
page of zeros at address zero on the VAX - in which case loads via
a NULL pointer would return zeros, and stores would fault. System V
would fault on such reads.

This bit more than a few programmers at the time.

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


#400405

Fromantispam@fricas.org (Waldek Hebisch)
Date2026-07-25 16:30 +0000
Message-ID<1142oc0$14b1e$1@paganini.bofh.team>
In reply to#400382
David Brown <david.brown@hesbynett.no> wrote:
> On 24/07/2026 00:11, Keith Thompson wrote:
> 
> The trouble with your argument here is that a pointer with value 0 is 
> not necessarily a null pointer (and I'm assuming an implementation where 
> null pointers have a value 0, not anything weirder than that).
> 
> Null pointers are generated from null pointer constants - 0, (void*) 0, 
> and nullptr.  If you have a pointer that happens to contain the value 0 
> but it did not come from a null pointer constant, it is not a null 
> pointer and dereferencing it is not inherently UB.  (Of course it is 
> still UB if it does not point to a valid object of appropriate type.)
> 
> The evaluation of "!p" is based on a comparison of "p" to the value 0 - 
> it will be true if p contains the value 0.  (This point is perhaps the 
> weak link in my reasoning - maybe "!p" is only true if "p" is actually a 
> null pointer.  However, I am confident that all real implementations, 
> where null pointers are value 0, act by comparison of the value.)
> 
> As far as I can see, therefore, "p" can be a valid pointer to an object 
> of appropriate type, not be a null pointer, and still have value 0 and 
> have "!p" evaluate to 1.
 
I did not check the standard, but if the standard allows this, then
this is clearly a bug in the standard.  To say it differently,
any C compiler when '!p' can evaluate to 1 for pointer p to a valid
object is broken.  Implementing '!p' via machine level comparison
to 0 works only when null pointer is represented by 0, otherwise
compiler must to whatever is necessary to get right result of the
comparison.
 
-- 
                              Waldek Hebisch

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


#400444

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2026-07-27 09:33 -0400
Message-ID<1147mnu$37r54$1@dont-email.me>
In reply to#400405
On 2026-07-25 12:30, Waldek Hebisch wrote:
> David Brown <david.brown@hesbynett.no> wrote:
...>> The evaluation of "!p" is based on a comparison of "p" to the
value 0 -
>> it will be true if p contains the value 0. ...

False.

>> ... (This point is perhaps the 
>> weak link in my reasoning - maybe "!p" is only true if "p" is actually a 
>> null pointer. ...

Correct.

>> ... However, I am confident that all real implementations, 
>> where null pointers are value 0, ... 

I doubt that - if it were true, there would be pressure on the committee
to mandate such a representation.

>> ...  act by comparison of the value.)
>> As far as I can see, therefore, "p" can be a valid pointer to an object 
>> of appropriate type, not be a null pointer, and still have value 0 and 
>> have "!p" evaluate to 1.
>  
> I did not check the standard, but if the standard allows this, then
> this is clearly a bug in the standard.

The standard is quite clear. !p returns 0 if p compares equal to 0, and
1 otherwise. When a pointer is compared with 0, the 0 gets  implicitly
converted to a null pointer of the same type. All null pointers compare
equal. Therefore !p tests whether 0 is a null pointer, not whether it
has a representation with all bits cleared.

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


#400445

FromJohann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid>
Date2026-07-28 00:22 +0800
Message-ID<ABL9S.9473$1xtd.2670@fx01.ams4>
In reply to#400444
On 27/07/2026 9:33 PM, James Kuyper wrote:
> On 2026-07-25 12:30, Waldek Hebisch wrote:
>> David Brown <david.brown@hesbynett.no> wrote:
> ...>> The evaluation of "!p" is based on a comparison of "p" to the
> value 0 -
>>> it will be true if p contains the value 0. ...
> 
> False.
> 
>>> ... (This point is perhaps the
>>> weak link in my reasoning - maybe "!p" is only true if "p" is actually a
>>> null pointer. ...
> 
> Correct.
> 
>>> ... However, I am confident that all real implementations,
>>> where null pointers are value 0, ...
> 
> I doubt that - if it were true, there would be pressure on the committee
> to mandate such a representation.
> 
>>> ...  act by comparison of the value.)
>>> As far as I can see, therefore, "p" can be a valid pointer to an object
>>> of appropriate type, not be a null pointer, and still have value 0 and
>>> have "!p" evaluate to 1.
>>   
>> I did not check the standard, but if the standard allows this, then
>> this is clearly a bug in the standard.
> 
> The standard is quite clear. !p returns 0 if p compares equal to 0, and
> 1 otherwise. When a pointer is compared with 0, the 0 gets  implicitly
> converted to a null pointer of the same type. All null pointers compare
> equal. Therefore !p tests whether 0 is a null pointer, not whether it
> has a representation with all bits cleared.
> 

I'm not in a position to do so yet, but you can trivially test this by
implementing "the null pointer" to be internally represented by 0xff..ff
where the .. represents your bitwith; 16bit, 32bit, 64bit, 128bit.

Then one of the first thing you notice, is that the integer zero needs
to convert to the 0xff..ff bit pattern when cast to a pointer.  After
that, implementing !p is trivial, for some value of trivial.


Happy compiler building!
-- 
Johann | email: invalid -> com | http://www.myrkraverk.com/blog/
I'm not from the Internet, I just work there. | via Easynews.com

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


#400449

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2026-07-27 12:58 -0700
Message-ID<1148d9b$3fv8p$1@kst.eternal-september.org>
In reply to#400445
Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> writes:
> On 27/07/2026 9:33 PM, James Kuyper wrote:
[...]
>> The standard is quite clear. !p returns 0 if p compares equal to 0,
>> and
>> 1 otherwise. When a pointer is compared with 0, the 0 gets  implicitly
>> converted to a null pointer of the same type. All null pointers compare
>> equal. Therefore !p tests whether 0 is a null pointer, not whether it
>> has a representation with all bits cleared.
>
> I'm not in a position to do so yet, but you can trivially test this by
> implementing "the null pointer" to be internally represented by 0xff..ff
> where the .. represents your bitwith; 16bit, 32bit, 64bit, 128bit.
>
> Then one of the first thing you notice, is that the integer zero needs
> to convert to the 0xff..ff bit pattern when cast to a pointer.  After
> that, implementing !p is trivial, for some value of trivial.

You'd have to create a compiler, or modify an existing one, to use a
non-zero representation for null pointers.  That's hardly "trivial".
(For example, default initialization for static objects could no
longer just zero the target object.)

I don't think there are any modern C compilers that don't use
all-bits-zero for null pointers.  Other representations are of
course valid, but tend not to be worth the trouble.

I wouldn't be terribly surprised if a future standard mandated
all-bits-zero for null pointers -- or if it didn't.

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */

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


Page 1 of 10  [1] 2 3 … 10  Next page →

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


csiph-web