Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #394650 > unrolled thread
| Started by | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| First post | 2025-10-22 09:45 -0300 |
| Last post | 2025-11-24 11:52 -0600 |
| Articles | 20 on this page of 248 — 14 participants |
Back to article view | Back to comp.lang.c
_BitInt(N) Thiago Adams <thiago.adams@gmail.com> - 2025-10-22 09:45 -0300
Re: _BitInt(N) BGB <cr88192@gmail.com> - 2025-10-22 11:42 -0500
Re: _BitInt(N) Thiago Adams <thiago.adams@gmail.com> - 2025-10-22 14:23 -0300
Re: _BitInt(N) Thiago Adams <thiago.adams@gmail.com> - 2025-10-22 14:25 -0300
Re: _BitInt(N) BGB <cr88192@gmail.com> - 2025-10-22 14:03 -0500
Re: _BitInt(N) Philipp Klaus Krause <pkk@spth.de> - 2025-11-23 12:46 +0100
Re: _BitInt(N) antispam@fricas.org (Waldek Hebisch) - 2025-11-23 13:32 +0000
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-23 13:59 +0000
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-23 17:06 +0200
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-24 10:29 +0100
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-24 11:17 +0000
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-24 05:12 -0800
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-24 14:49 +0100
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-24 17:23 -0800
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-25 07:56 +0100
Re: _BitInt(N) antispam@fricas.org (Waldek Hebisch) - 2025-11-29 19:36 +0000
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-30 11:56 +0100
Re: _BitInt(N) antispam@fricas.org (Waldek Hebisch) - 2025-11-30 15:50 +0000
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-24 05:06 -0800
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-24 15:27 +0200
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-24 14:51 +0100
Re: _BitInt(N) Philipp Klaus Krause <pkk@spth.de> - 2025-11-29 22:06 +0100
Re: _BitInt(N) BGB <cr88192@gmail.com> - 2025-11-29 17:10 -0600
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-29 17:32 -0800
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-30 11:46 +0200
Re: _BitInt(N) Philipp Klaus Krause <pkk@spth.de> - 2025-11-30 11:12 +0100
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-30 12:07 +0100
Re: _BitInt(N) antispam@fricas.org (Waldek Hebisch) - 2025-11-23 17:55 +0000
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-23 14:38 -0800
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-24 00:30 +0000
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-24 12:17 +0100
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-24 13:44 +0200
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-24 15:02 +0100
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-24 12:31 +0000
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-24 05:33 -0800
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-24 14:41 +0000
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-24 16:46 -0800
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-24 15:41 +0100
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-24 18:35 +0000
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-24 21:26 +0100
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-24 22:27 +0000
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-24 18:10 -0800
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-25 21:25 +0100
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-25 21:58 +0000
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-25 15:20 -0800
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-26 02:08 +0000
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-25 19:06 -0800
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-26 11:52 +0200
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-26 13:15 +0100
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-26 15:08 +0200
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-25 19:21 -0800
Re: _BitInt(N) Philipp Klaus Krause <pkk@spth.de> - 2025-11-29 22:40 +0100
Re: _BitInt(N) James Kuyper <jameskuyper@alumni.caltech.edu> - 2025-11-29 22:04 -0500
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-26 08:55 +0100
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-26 12:05 +0000
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-26 15:49 +0100
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-26 15:44 +0000
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-26 17:37 +0100
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-26 18:42 +0000
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-26 21:43 +0100
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-26 22:19 +0000
Re: _BitInt(N) antispam@fricas.org (Waldek Hebisch) - 2025-11-27 02:32 +0000
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-27 12:46 +0000
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-27 14:39 +0100
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-27 11:43 +0100
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-27 12:20 +0000
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-27 14:02 +0100
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-27 16:02 +0200
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-27 21:15 +0100
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-28 00:15 +0200
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-28 09:46 +0100
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-28 13:12 +0200
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-28 12:45 +0100
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-28 15:33 +0200
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-28 15:47 +0100
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-29 19:23 +0200
Re: _BitInt(N) antispam@fricas.org (Waldek Hebisch) - 2025-11-29 00:20 +0000
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-29 19:30 +0200
Re: _BitInt(N) BGB <cr88192@gmail.com> - 2025-11-28 13:09 -0600
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-28 22:43 +0000
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-27 17:13 +0000
Re: _BitInt(N) Ike Naar <ike@sdf.org> - 2025-11-27 17:38 +0000
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-27 17:59 +0000
Re: _BitInt(N) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-11-28 03:33 +0100
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-28 11:49 +0000
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-28 14:46 +0000
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-28 15:23 -0800
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-29 00:08 +0000
Re: _BitInt(N) antispam@fricas.org (Waldek Hebisch) - 2025-11-29 03:12 +0000
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-28 19:38 -0800
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-29 11:24 +0000
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-29 14:45 +0100
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-29 14:40 +0000
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-29 17:15 +0100
Re: _BitInt(N) James Kuyper <jameskuyper@alumni.caltech.edu> - 2025-11-29 10:27 -0500
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-29 16:29 -0800
Re: _BitInt(N) James Kuyper <jameskuyper@alumni.caltech.edu> - 2025-11-29 22:08 -0500
Re: _BitInt(N) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-12-20 11:24 -0800
Re: _BitInt(N) antispam@fricas.org (Waldek Hebisch) - 2025-12-21 00:18 +0000
Re: _BitInt(N) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-12-21 23:07 -0800
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-12-22 02:51 -0800
Re: _BitInt(N) Kaz Kylheku <046-301-5902@kylheku.com> - 2025-12-22 19:23 +0000
Re: _BitInt(N) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-01-07 03:01 -0800
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-12-20 18:22 -0800
Re: _BitInt(N) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-01-06 21:57 -0800
Re: _BitInt(N) James Kuyper <jameskuyper@alumni.caltech.edu> - 2025-12-20 21:27 -0500
Re: _BitInt(N) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-01-06 21:51 -0800
Re: _BitInt(N) Kaz Kylheku <046-301-5902@kylheku.com> - 2025-12-21 02:27 +0000
Re: _BitInt(N) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-12-21 22:48 -0800
Re: _BitInt(N) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-11-29 03:26 +0100
Re: _BitInt(N) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-11-29 03:32 +0100
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-29 12:24 +0000
Re: _BitInt(N) James Kuyper <jameskuyper@alumni.caltech.edu> - 2025-11-28 09:48 -0500
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-28 11:41 +0100
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-28 19:46 +0000
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-28 21:58 +0100
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-27 15:59 -0800
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-28 00:11 +0000
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-27 16:39 -0800
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-28 01:49 +0000
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-27 19:36 -0800
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-12-04 17:58 -0800
[meta] Newsreader and formatting (was Re: _BitInt(N)) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-11-28 02:56 +0100
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-12-01 14:59 +0200
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-12-01 14:18 +0100
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-12-01 12:06 -0800
Re: _BitInt(N) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-12-01 23:59 +0100
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-12-02 08:31 +0100
Re: _BitInt(N) Philipp Klaus Krause <pkk@spth.de> - 2025-12-02 12:14 +0100
[OT] Keyboard layout (was Re: _BitInt(N)) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-12-02 14:01 +0100
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-12-02 15:33 -0800
Re: _BitInt(N) Philipp Klaus Krause <pkk@spth.de> - 2025-12-03 09:23 +0100
Re: _BitInt(N) Richard Heathfield <rjh@cpax.org.uk> - 2025-12-03 08:29 +0000
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-12-03 02:16 -0800
Re: _BitInt(N) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-12-15 11:01 -0800
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-12-15 14:19 -0800
Re: _BitInt(N) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-12-21 22:24 -0800
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-12-02 12:21 +0000
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-12-02 13:45 +0100
Re: _BitInt(N) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-12-02 14:15 +0100
Block syntax (was Re: _BitInt(N)) bart <bc@freeuk.com> - 2025-12-02 14:12 +0000
Re: _BitInt(N) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-12-02 13:53 +0100
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-12-02 19:55 +0200
Re: _BitInt(N) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-12-02 19:37 +0100
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-12-02 21:07 +0100
Re: _BitInt(N) Ike Naar <ike@sdf.org> - 2025-11-27 08:10 +0000
Re: _BitInt(N) antispam@fricas.org (Waldek Hebisch) - 2025-11-27 01:30 +0000
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-27 02:18 +0000
Re: _BitInt(N) antispam@fricas.org (Waldek Hebisch) - 2025-11-27 04:12 +0000
Re: _BitInt(N) antispam@fricas.org (Waldek Hebisch) - 2025-11-29 20:24 +0000
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-29 22:58 +0000
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-29 16:46 -0800
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-30 02:30 +0000
Re: _BitInt(N) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-11-30 05:31 +0100
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-30 12:51 +0000
Re: _BitInt(N) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-11-30 18:17 +0100
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-30 17:55 +0000
Re: _BitInt(N) antispam@fricas.org (Waldek Hebisch) - 2025-12-01 00:08 +0000
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-12-01 01:14 +0000
Re: _BitInt(N) antispam@fricas.org (Waldek Hebisch) - 2025-12-01 04:10 +0000
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-12-01 14:41 +0000
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-12-01 16:24 +0100
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-12-01 17:19 +0000
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-12-01 19:33 +0100
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-12-01 20:14 +0000
Re: _BitInt(N) antispam@fricas.org (Waldek Hebisch) - 2025-12-02 01:04 +0000
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-12-01 18:21 -0800
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-12-01 12:34 -0800
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-12-01 22:01 +0000
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-12-01 15:01 -0800
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-12-01 11:33 +0100
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-12-01 11:29 +0000
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-12-01 14:10 +0100
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-12-01 08:56 -0800
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-12-01 19:38 +0100
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-12-01 12:42 -0800
Re: _BitInt(N) Philipp Klaus Krause <pkk@spth.de> - 2025-12-02 22:17 +0100
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-12-03 09:25 +0100
Re: _BitInt(N) James Kuyper <jameskuyper@alumni.caltech.edu> - 2025-12-03 06:17 -0500
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-12-03 10:07 -0800
Re: _BitInt(N) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-12-15 08:19 -0800
Re: _BitInt(N) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-12-15 08:21 -0800
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-30 18:05 -0800
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-29 20:32 -0800
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-30 12:22 +0200
Re: _BitInt(N) Philipp Klaus Krause <pkk@spth.de> - 2025-11-30 11:41 +0100
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-30 12:28 +0100
Re: _BitInt(N) Philipp Klaus Krause <pkk@spth.de> - 2025-11-30 13:35 +0100
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-30 15:14 +0100
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-30 12:09 +0000
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-24 18:03 -0800
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-25 11:38 +0000
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-25 14:12 +0200
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-25 14:57 +0000
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-25 18:29 +0200
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-25 18:33 +0000
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-26 11:12 +0200
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-26 12:45 +0000
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-26 15:31 +0200
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-26 11:29 +0200
Re: _BitInt(N) James Kuyper <jameskuyper@alumni.caltech.edu> - 2025-11-26 21:19 -0500
Re: _BitInt(N) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-12-15 08:29 -0800
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-25 21:54 +0100
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-25 13:42 -0800
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-26 12:01 +0200
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-26 15:08 +0100
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-26 13:24 +0100
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-25 23:11 +0200
Re: _BitInt(N) BGB <cr88192@gmail.com> - 2025-11-26 17:04 -0600
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-27 01:05 +0000
Re: _BitInt(N) antispam@fricas.org (Waldek Hebisch) - 2025-11-27 02:54 +0000
Re: _BitInt(N) Philipp Klaus Krause <pkk@spth.de> - 2025-11-29 22:17 +0100
Re: _BitInt(N) antispam@fricas.org (Waldek Hebisch) - 2025-11-29 22:41 +0000
Re: _BitInt(N) Philipp Klaus Krause <pkk@spth.de> - 2025-11-30 00:17 +0100
Re: _BitInt(N) antispam@fricas.org (Waldek Hebisch) - 2025-11-30 01:22 +0000
Re: _BitInt(N) Philipp Klaus Krause <pkk@spth.de> - 2025-11-30 11:00 +0100
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-30 11:05 +0200
Re: _BitInt(N) Philipp Klaus Krause <pkk@spth.de> - 2025-11-30 10:51 +0100
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-30 13:10 +0000
Re: _BitInt(N) Philipp Klaus Krause <pkk@spth.de> - 2025-11-30 15:26 +0100
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-30 15:09 +0000
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-30 17:26 +0100
Re: _BitInt(N) antispam@fricas.org (Waldek Hebisch) - 2025-11-30 21:53 +0000
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-30 17:32 -0800
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-12-01 08:36 +0100
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-12-01 11:37 +0000
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-12-01 14:37 +0100
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-12-01 14:14 +0000
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-12-01 16:28 +0100
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-30 12:39 +0100
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-24 14:10 +0200
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-24 04:29 -0800
Re: _BitInt(N) BGB <cr88192@gmail.com> - 2025-11-23 21:39 -0600
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-24 11:45 +0000
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-24 13:57 +0200
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-24 12:56 +0000
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-24 15:17 +0200
Re: _BitInt(N) David Brown <david.brown@hesbynett.no> - 2025-11-24 15:59 +0100
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-24 05:35 -0800
Re: _BitInt(N) bart <bc@freeuk.com> - 2025-11-24 14:21 +0000
Re: _BitInt(N) BGB <cr88192@gmail.com> - 2025-11-24 13:12 -0600
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-24 17:00 -0800
Re: _BitInt(N) BGB <cr88192@gmail.com> - 2025-11-24 20:10 -0600
Re: _BitInt(N) Philipp Klaus Krause <pkk@spth.de> - 2025-11-29 22:30 +0100
Re: _BitInt(N) antispam@fricas.org (Waldek Hebisch) - 2025-11-30 01:51 +0000
Re: _BitInt(N) Michael S <already5chosen@yahoo.com> - 2025-11-30 11:22 +0200
Re: _BitInt(N) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-11-24 04:37 -0800
Re: _BitInt(N) BGB <cr88192@gmail.com> - 2025-11-24 11:52 -0600
Page 2 of 13 — ← Prev page 1 [2] 3 4 … 13 Next page →
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2025-11-24 14:51 +0100 |
| Message-ID | <10g1nsd$2f8lb$2@dont-email.me> |
| In reply to | #395411 |
On 24/11/2025 14:06, Keith Thompson wrote: > David Brown <david.brown@hesbynett.no> writes: > [...] >> Yes, exactly. At the call site, the size of the _BitInt type is >> always a known compile-time constant, so it can easily be passed on. >> Thus : >> >> _BitInt(N) x; >> _BitInt(M) y; >> _BitInt(NM) z = x * y; >> >> can be implemented as something like : >> >> __bit_int_signed_mult(NM, (unsigned char *) &z, >> N, (const unsigned char *) &x, >> M, (const unsigned char *) &y); > > That looks like it's supposed to avoid overflow (I'm assuming NM is N + M), but > it wouldn't work. The type of a C expression is almost always determined > by the expression itself, regardless of the context in which it appears. > The type of x * y is _BitInt(max(N, M)), not _BitInt(N+M), so it can > overflow even if the full result would fit into z. > > You can do this instead (not tested): > > _BitInt(N) x; > _BitInt(M) y; > _Bit_Int(N+M) z = (_BitInt(N+M))x * y; > > (I'm assuming N+M is sufficient, but I might have missed an off-by-one > error somewhere.) > It /looks/ like NM means "N + M" (or N * M, as both Bart and I wrote without thinking), but that was not my intention. I simply meant a constant that may be chosen differently from N and M, and did not want to go on to the letter O. In hindsight, NM was a poor choice.
[toc] | [prev] | [next] | [standalone]
| From | Philipp Klaus Krause <pkk@spth.de> |
|---|---|
| Date | 2025-11-29 22:06 +0100 |
| Message-ID | <10gfn95$sda3$1@solani.org> |
| In reply to | #395388 |
Am 23.11.25 um 16:06 schrieb Michael S: > > Upper limit is implementation-defined. > On both existing implementations the limit (on 64-bit targets) appears > to be 2**16 or 2**16-1. I don't remember which one. Thisis comp.lang.c, not comp.lang.c++. There still are implementations of C other than GCC and clang. E.g. SDCC has a limit of 64. Philipp
[toc] | [prev] | [next] | [standalone]
| From | BGB <cr88192@gmail.com> |
|---|---|
| Date | 2025-11-29 17:10 -0600 |
| Message-ID | <10gfulf$3qoko$1@dont-email.me> |
| In reply to | #395575 |
On 11/29/2025 3:06 PM, Philipp Klaus Krause wrote:
> Am 23.11.25 um 16:06 schrieb Michael S:
>>
>> Upper limit is implementation-defined.
>> On both existing implementations the limit (on 64-bit targets) appears
>> to be 2**16 or 2**16-1. I don't remember which one.
>
> Thisis comp.lang.c, not comp.lang.c++. There still are implementations
> of C other than GCC and clang. E.g. SDCC has a limit of 64.
>
Yes.
There are plenty of C compilers other than just GCC and Clang.
Main ones I am use being
GCC and Clang: Make most sense in WSL and similar;
GCC works OK as a cross-compiler for RISC-V and similar.
But, even then, still some rough edges IME.
MSVC, mostly for Windows Native development.
But, still lacks most newer features.
It took nearly 15 years to start adding C99 stuff.
Now at loosely mostly at C99 / C11 levels.
BGBCC: Custom compiler mostly for a custom ISA.
But can also target RISC-V, albeit using PE/COFF and some wonk.
Not meant to address the same use-cases as GCC or similar (*1)
*1: In cases where GCC or Clang serves the use-case, better to just use
these. I did my own compiler partly for historical reasons, it continued
on mostly as:
GCC and Clang are too large and painful to rebuild from source;
At the time, LCC wouldn't have really saved any effort.
Well, and partial reasons it gained RISC-V being:
My custom CPU core gained RV64 support;
I had already been using RV in a few other contexts;
GCC wasn't sufficiently addressing my uses.
Ironically, my compiler lacks an x86 or x86-64 backend mostly because
the use-cases I have for it don't really need it (and for what cases are
not addressed by MSVC or GCC or Clang or similar, are often addressed
well enough by using an ISA emulator; where a sensibly designed ISA can
also work well in a VM).
There was once an x86 backend, but it was lost a long time ago.
Though, for funky reasons, ironically a lot more recent work in the
compiler has been going into things like file-conversion and asset
packaging stuff (partly as "scope creep" had partly also led to it being
used as an asset packager and file converter). Well, and I also
sometimes have uses for an asset-packager tool (well, even if, say,
arguably a C compiler and asset packager are ideally separate tools, but
alas...).
Well, say:
It sometimes made sense to include files into the "resource section";
The original resource-section had been partly replaced with a WAD
variant. Derived from WAD2, just with a self-referencing header and lump
offsets based on RVA; the header including a self-reference to make it
easier to locate the image/RVA base if given a pointer to the header
(though can also locate the header if given the image base RVA). Though,
this was because the original resource-section used with PE/COFF kinda
sucked, and no real reason to use it if the target is not Windows.
In this case, it is a descendant of the WAD format used by Doom,
differing mostly in that while Doom WADs had 8 character names, WAD2 had
16 characters, and a few other features (but not that much fundamentally
different).
But, then one might want to develop an asset in one format (such as PNG)
but then put it in a resource in another format (such as 16 or 256 color
BMP), so it makes sense to have a converter. And, this is how it starts...
But, then also ended up with a WAD4 format, which was more advanced,
could function more like a VFS. Decided not to describe the WAD family
tree, but:
The basic idea of WAD originated in Doom and related games, and was
carried over (in a modified form to Quake 1 and Half-Life). Some of my
stuff uses a variant of the WAD2 format (from Quake), with some more
advanced scenarios using WAD4; which is in turn, a simpler and lower
overhead format if compared with using ZIP (Quake3 and Doom3 and
similar, followed by many newer projects, had went to using ZIP for a
VFS; but using ZIP in this way is needlessly complicated and expensive).
Though, in WAD4, it encodes the directory structure piecewise (by
organizing lumps into a tree structure), rather than expressing the full
path in a single name (as was done in PACK and the ZIP-based PK3 VFS).
In some cases, there are merits to breaking things up and using a
directory walk rather than a monolithic file path.
...
> Philipp
>
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2025-11-29 17:32 -0800 |
| Message-ID | <87o6ok9ug3.fsf@example.invalid> |
| In reply to | #395575 |
Philipp Klaus Krause <pkk@spth.de> writes:
> Am 23.11.25 um 16:06 schrieb Michael S:
>> Upper limit is implementation-defined.
>> On both existing implementations the limit (on 64-bit targets) appears
>> to be 2**16 or 2**16-1. I don't remember which one.
Recent versions of gcc have BITINT_MAXWIDTH == 65535.
llvm/clang has BITINT_MAXWIDTH == 8388608 (2**23) (and some serious
performance problems with multiplication and division for large _BitInt
types).
> Thisis comp.lang.c, not comp.lang.c++. There still are implementations
> of C other than GCC and clang. E.g. SDCC has a limit of 64.
I didn't see any references to C++ in the parent article. But it's
interesting that SDCC support _BitInt.
--
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]
| From | Michael S <already5chosen@yahoo.com> |
|---|---|
| Date | 2025-11-30 11:46 +0200 |
| Message-ID | <20251130114614.00001d02@yahoo.com> |
| In reply to | #395587 |
On Sat, 29 Nov 2025 17:32:12 -0800 Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote: > Philipp Klaus Krause <pkk@spth.de> writes: > > Am 23.11.25 um 16:06 schrieb Michael S: > >> Upper limit is implementation-defined. > >> On both existing implementations the limit (on 64-bit targets) > >> appears to be 2**16 or 2**16-1. I don't remember which one. > > Recent versions of gcc have BITINT_MAXWIDTH == 65535. > > llvm/clang has BITINT_MAXWIDTH == 8388608 (2**23) (and some serious > performance problems with multiplication and division for large > _BitInt types). > According to my measurements, it also have serious performance problems with division that I'd call 'big' rather than large. Like 256 bits. Also, it has performance problems with addition and subtraction of large _BitInt types, like in example of Anton Ertl (A+B+C, for N=2**16-64) that we discussed not long ago on comp.arch. However, in this particular case, gcc is only slightly better in speed (but a lot better in code size). > > Thisis comp.lang.c, not comp.lang.c++. There still are > > implementations of C other than GCC and clang. E.g. SDCC has a > > limit of 64. > > I didn't see any references to C++ in the parent article. But it's > interesting that SDCC support _BitInt. > I'd guess that Philipp Klaus Krause meant to say that there are many more independently developed C compilers than there are C++ compilers, especially so if we only count those that try to be up to date with the most recent language standards. He is, of course, right and I was, of course, wrong in my assumption that no other compilers except gcc and clang implemented _BitInt at the moment.
[toc] | [prev] | [next] | [standalone]
| From | Philipp Klaus Krause <pkk@spth.de> |
|---|---|
| Date | 2025-11-30 11:12 +0100 |
| Message-ID | <10gh59o$t89e$3@solani.org> |
| In reply to | #395587 |
Am 30.11.25 um 02:32 schrieb Keith Thompson: >> Thisis comp.lang.c, not comp.lang.c++. There still are implementations >> of C other than GCC and clang. E.g. SDCC has a limit of 64. > > I didn't see any references to C++ in the parent article. But it's > interesting that SDCC support _BitInt. > I'm not sure, but I think SDCC was the probably first real _BitInt implementation. SDCC got _BitInt in early 2022, GCC in late 2023. clang had _ExtInt before anyone had _BitInt, and their documentation for _BitInt claims "This type was previously implemented in Clang with the same semantics, but spelled _ExtInt(N)". However AFAIK that is not entirely true, integer promotion behaves differently for _ExtInt vs. _BitInt. When the proposals were brought to WG14, _ExtInt would promote to int for _ExtInt(N) with N <= sizeof(int) * CHAR_BITS, while _BitInt doesn't. And AFAIR, that difference is one of the reasons why the C standard places quite some restrictions on _BitInt, disallowing the use of _BitInt in many cases - it was considered too surprising to the user if e.g. by allowing a _BitInt to be used for ptrdiff_t, one could have a conforming implementation where sizeof(ptrdiff_t) < sizeof(int), but ptrdiff_t doesn't promote to int. Philipp
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2025-11-30 12:07 +0100 |
| Message-ID | <10gh8h3$8ooq$2@dont-email.me> |
| In reply to | #395587 |
On 30/11/2025 02:32, Keith Thompson wrote: > Philipp Klaus Krause <pkk@spth.de> writes: >> Am 23.11.25 um 16:06 schrieb Michael S: >>> Upper limit is implementation-defined. >>> On both existing implementations the limit (on 64-bit targets) appears >>> to be 2**16 or 2**16-1. I don't remember which one. > > Recent versions of gcc have BITINT_MAXWIDTH == 65535. > > llvm/clang has BITINT_MAXWIDTH == 8388608 (2**23) (and some serious > performance problems with multiplication and division for large _BitInt > types). > >> Thisis comp.lang.c, not comp.lang.c++. There still are implementations >> of C other than GCC and clang. E.g. SDCC has a limit of 64. > > I didn't see any references to C++ in the parent article. But it's > interesting that SDCC support _BitInt. > It is also worth remembering that gcc does /not/ as yet support _BitInt on most targets. AFAIK, it only supports them on x86 and AArch64. I think it is disappointing that the C23 standard allows BITINT_MAXWIDTH to be as low as the bit-width of "long long int" (typically 64 bits). I do see _BitInt of 64-bit and less being useful, but I would like to be able to use larger sizes without worrying about portability. The gcc limit is, I think, more than sufficient for realistic usage (though it I think a power of two size makes more sense than one less than a power of two). Obviously the type of targets SDCC supports could not practically support huge _BitInt's anyway - typically they have ram of only a few KB.
[toc] | [prev] | [next] | [standalone]
| From | antispam@fricas.org (Waldek Hebisch) |
|---|---|
| Date | 2025-11-23 17:55 +0000 |
| Message-ID | <10fvhqo$3dif8$1@paganini.bofh.team> |
| In reply to | #395387 |
bart <bc@freeuk.com> wrote:
> On 23/11/2025 13:32, Waldek Hebisch wrote:
>> Philipp Klaus Krause <pkk@spth.de> wrote:
>>> Am 22.10.25 um 14:45 schrieb Thiago Adams:
>>>>
>>>>
>>>> Is anyone using or planning to use this new C23 feature?
>>>> What could be the motivation?
>>>>
>>>>
>>>
>>> Saving memory by using the smallest multiple-of-8 N that will do.
>>
>> IIUC nothing in the standard says that it is smallest multiple-of-8.
>> Using gcc-15.1 on AMD-64 is get 'sizeof(_BitInt(22))' equal to 4,
>> while the number cound fit in 3 bytes.
>
> The rationale mentions a use-case where there is a custom processor that
> might actually have a 22-bit hardware types.
>
> Implementing such odd-size types on regular 8/16/32/64-bit hardware is
> full of problems if you want to do it without padding (in order to get
> the savings). On even with padding (to get the desired overflow semantics).
>
> Such as working out how pointers to them will work.
Yes. That is why type is rounded up. For unsigned types compiler
may need to generate explicit masking operation (to discard excess
bits), but for signed types compiler may perform operations
in increased precision.
>>> Also
>>> being able to use bit-fields wider than int.
>>
>> For me main gain is reasonably standard syntax for integers bigger
>> that 64 bits.
>
> Standard syntax I guess would be something like int128_t and int256_t.
> Such wider integers tend to be powers of two.
Powers of two are used when hardware operates only on power of two
sized pieces. But for multiword integers in general there is no reason
to use even number of words and AFAICS gcc uses odd number of
words when it is enough.
Note that for arithmetic on sub-word numbers on modern machines
promoting them to words usually gives the same performance.
But smaller number of words is likely to lead to faster
operation, so it makes no sense to insist on powers of two.
--
Waldek Hebisch
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2025-11-23 14:38 -0800 |
| Message-ID | <87ms4c4bom.fsf@example.invalid> |
| In reply to | #395387 |
bart <bc@freeuk.com> writes:
> On 23/11/2025 13:32, Waldek Hebisch wrote:
>> Philipp Klaus Krause <pkk@spth.de> wrote:
>>> Am 22.10.25 um 14:45 schrieb Thiago Adams:
>>>> Is anyone using or planning to use this new C23 feature?
>>>> What could be the motivation?
>>>
>>> Saving memory by using the smallest multiple-of-8 N that will do.
>> IIUC nothing in the standard says that it is smallest multiple-of-8.
>> Using gcc-15.1 on AMD-64 is get 'sizeof(_BitInt(22))' equal to 4,
>> while the number cound fit in 3 bytes.
>
> The rationale mentions a use-case where there is a custom processor
> that might actually have a 22-bit hardware types.
What rationale are you referring to? There hasn't been an official ISO
C Rationale document since C99.
> Implementing such odd-size types on regular 8/16/32/64-bit hardware is
> full of problems if you want to do it without padding (in order to get
> the savings). On even with padding (to get the desired overflow
> semantics).
>
> Such as working out how pointers to them will work.
Why would pointers to _BitInt types be a problem? A _BitInt object is
a fixed-size chunk of memory, similar to a struct object.
>>> Also being able to use bit-fields wider than int.
>> For me main gain is reasonably standard syntax for integers bigger
>> that 64 bits.
>
> Standard syntax I guess would be something like int128_t and
> int256_t. Such wider integers tend to be powers of two.
>
> But there are two problems with _BitInt:
>
> * Any odd sizes are allowed, such as _BitInt(391)
Why is that a problem? If you don't want odd-sized types, don't use them.
> * There appears to be no upper limit on size, so _BitInt(2997901) is a
> valid type
The upper limit is specified by the implementation as BITINT_MAXWIDTH, a
macro defined in <limits.h>.
For gcc 15.2.0 on x86_64, BITINT_MAXWIDTH is 65535 (2**16-1).
For clang 21.1.5 it's 8388608 (2**23 bits, 1048576 bytes).
clang seems to have some problems with _BitInt(8388608). For example,
this program:
#include <limits.h>
_BitInt(BITINT_MAXWIDTH) n = 42;
int main(void) {
n *= n;
}
takes a *long* time to compile with clang. I believe it's generating
inline code to do the 8388608 by 8388608 bit multiplication.
> So what is the result type of multiplying values of those two types?
_BitInt types are exempt from the integer promotion rules (so _BitInt(3)
doesn't promote to int), but the usual arithmetic conversions apply.
If you multiply values of two _BitInt types, the result is the wider of
the two types.
N3220 is a draft of C23.
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3220.pdf
> Integer sizes greater than 1K or 2K bits should use an arbitrary
> precision type (which is how large _BitInts will likely be implemented
> anyway), where the precision is a runtime attribute.
_BitInt(n) objects are fixed-size. Addition and subtraction should be
fairly straightforward. For multiplication and division, gcc generates
calls to __mulbitint3 and __divmodbitint4, and clang generates huge
amounts of inline code. My guess is that future llvm/clang releases
will handle _BitInt types more efficiently.
--
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]
| From | bart <bc@freeuk.com> |
|---|---|
| Date | 2025-11-24 00:30 +0000 |
| Message-ID | <10g08vm$1us25$1@dont-email.me> |
| In reply to | #395395 |
On 23/11/2025 22:38, Keith Thompson wrote:
> bart <bc@freeuk.com> writes:
>> On 23/11/2025 13:32, Waldek Hebisch wrote:
>>> Philipp Klaus Krause <pkk@spth.de> wrote:
>>>> Am 22.10.25 um 14:45 schrieb Thiago Adams:
>>>>> Is anyone using or planning to use this new C23 feature?
>>>>> What could be the motivation?
>>>>
>>>> Saving memory by using the smallest multiple-of-8 N that will do.
>>> IIUC nothing in the standard says that it is smallest multiple-of-8.
>>> Using gcc-15.1 on AMD-64 is get 'sizeof(_BitInt(22))' equal to 4,
>>> while the number cound fit in 3 bytes.
>>
>> The rationale mentions a use-case where there is a custom processor
>> that might actually have a 22-bit hardware types.
>
> What rationale are you referring to? There hasn't been an official ISO
> C Rationale document since C99.
See Introduction and Rationale here:
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2709.pdf
>
>> Implementing such odd-size types on regular 8/16/32/64-bit hardware is
>> full of problems if you want to do it without padding (in order to get
>> the savings). On even with padding (to get the desired overflow
>> semantics).
>>
>> Such as working out how pointers to them will work.
>
> Why would pointers to _BitInt types be a problem? A _BitInt object is
> a fixed-size chunk of memory, similar to a struct object.
Saving memory was mentioned. To achieve that means having bitfields that
may not start at bit 0 of a byte, and may cross byte- or word-boundaries.
For example, an array of 1M 5-bit values would occupy 1M 8-bit bytes,
but storing packed values means it would use only 625K bytes.
Anyway, pointers to individual values, or to some arbitrary element or
slice of such an array, would need some extra info.
>>>> Also being able to use bit-fields wider than int.
>>> For me main gain is reasonably standard syntax for integers bigger
>>> that 64 bits.
>>
>> Standard syntax I guess would be something like int128_t and
>> int256_t. Such wider integers tend to be powers of two.
>>
>> But there are two problems with _BitInt:
>>
>> * Any odd sizes are allowed, such as _BitInt(391)
>
> Why is that a problem? If you don't want odd-sized types, don't use them.
It is an unnecessary complication. There will be a lot of extra rules
that maybe partly 'implementation defined', so behaviour may vary. And
people WILL uses those types because they are there, and likely they
will be inefficient.
What happens when a 391-bit type, even unsigned, overflows? These larger
types are likely to use a multiple of 64-bits, and for 391 bits will
need 7 x 64 bits, of which the last word will have 57 bits of padding.
It's very messy.
Specifying a multiple of 64 bits is better; a power of two even better.
>> * There appears to be no upper limit on size, so _BitInt(2997901) is a
>> valid type
>
> The upper limit is specified by the implementation as BITINT_MAXWIDTH, a
> macro defined in <limits.h>.
>
> For gcc 15.2.0 on x86_64, BITINT_MAXWIDTH is 65535 (2**16-1).
> For clang 21.1.5 it's 8388608 (2**23 bits, 1048576 bytes).
>
> clang seems to have some problems with _BitInt(8388608). For example,
> this program:
>
> #include <limits.h>
>
> _BitInt(BITINT_MAXWIDTH) n = 42;
>
> int main(void) {
> n *= n;
> }
>
> takes a *long* time to compile with clang. I believe it's generating
> inline code to do the 8388608 by 8388608 bit multiplication.
Now try it with two disparate sizes.
>> So what is the result type of multiplying values of those two types?
>
> _BitInt types are exempt from the integer promotion rules (so _BitInt(3)
> doesn't promote to int), but the usual arithmetic conversions apply.
> If you multiply values of two _BitInt types, the result is the wider of
> the two types.
So multiplying even two one-million-bit types could overflow!
Such limits for /fixed-width/ integers are ridiculous.
You might say this is no different from defining an array of exactly
123,456 elements. But the use-cases are very different.
I starting going into details but I guess you don't care about such
matters or whether the feature makes much sense.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2025-11-24 12:17 +0100 |
| Message-ID | <10g1et7$2bmus$1@dont-email.me> |
| In reply to | #395396 |
On 24/11/2025 01:30, bart wrote:
> On 23/11/2025 22:38, Keith Thompson wrote:
>> bart <bc@freeuk.com> writes:
>>> On 23/11/2025 13:32, Waldek Hebisch wrote:
>>>> Philipp Klaus Krause <pkk@spth.de> wrote:
>>>>> Am 22.10.25 um 14:45 schrieb Thiago Adams:
>>>>>> Is anyone using or planning to use this new C23 feature?
>>>>>> What could be the motivation?
>>>>>
>>>>> Saving memory by using the smallest multiple-of-8 N that will do.
>>>> IIUC nothing in the standard says that it is smallest multiple-of-8.
>>>> Using gcc-15.1 on AMD-64 is get 'sizeof(_BitInt(22))' equal to 4,
>>>> while the number cound fit in 3 bytes.
>>>
>>> The rationale mentions a use-case where there is a custom processor
>>> that might actually have a 22-bit hardware types.
>>
>> What rationale are you referring to? There hasn't been an official ISO
>> C Rationale document since C99.
>
> See Introduction and Rationale here:
>
> https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2709.pdf
>
That's a proposal document, rather than that actual C standard. But it
is useful and relevant here, and explains some of the potential uses of
_BitInt.
>
>
>>
>>> Implementing such odd-size types on regular 8/16/32/64-bit hardware is
>>> full of problems if you want to do it without padding (in order to get
>>> the savings). On even with padding (to get the desired overflow
>>> semantics).
>>>
>>> Such as working out how pointers to them will work.
>>
>> Why would pointers to _BitInt types be a problem? A _BitInt object is
>> a fixed-size chunk of memory, similar to a struct object.
>
> Saving memory was mentioned. To achieve that means having bitfields that
> may not start at bit 0 of a byte, and may cross byte- or word-boundaries.
>
No, that is incorrect.
The proposal mentions saving /space/ as relevant in FPGAs - not saving
/memory/. The authors use-case here is in writing code that can be
compiled with a "normal" C compiler on a "normal" target, and also
compiled to FPGA /hardware/, with the same semantics. In hardware, a
5-bit by 5-bit single-cycle multiplier is very much smaller than an
8-bit by 8-bit multiplier, and orders of magnitude smaller than if the
5-bit integers are promoted to 32-bit before multiplying.
The proposal is not about saving /memory/. It specifically says that a
_BitInt(N) has the same size and alignment as the smallest basic type
that can contain it, until you get to N greater than 64-bit, in which
they are contained in an array of int64_t. (The reality is a little
more formal, to handle targets that have other sizes of their basic types.)
So on a "normal" target, a _BitInt(3) is the same size and alignment as
a uint8_t, a _BitInt(35) is effectively contained in an uint64_t, and an
array of 4 _BitInt(17) on a 32-bit system will take 16 bytes or 128
bits, not 68 bits.
As far as I can see, the C23 standard does not specify these details,
and leaves them up to the target ABI. But at the very least, they will
always take an integer number of bytes - unsigned char. There can never
be any crossing of byte boundaries.
I expect most "big" implementations to follow the proposals
recommendation with containers of 8, 16, 32 and 64 bits, then arrays of
64-bit chunks after that. I expect some smaller targets to be a bit
more flexible - 8-bit embedded targets are likely to use 8-bit chunks
for everything, and 16-bit and 32-bit devices will use 16-bit and 32-bit
chunks. I have not yet looked for implementations in order to check this.
Compilers targeting FPGA hardware generation are, by their nature, weird
in many ways. They will generate N-bit wide logic and registers for
local data and expressions. How they implement things like arrays in
memory will probably be very specialised - these are not tools you use
with arbitrary C code, and almost everything is specially written.
> For example, an array of 1M 5-bit values would occupy 1M 8-bit bytes,
> but storing packed values means it would use only 625K bytes.
>
> Anyway, pointers to individual values, or to some arbitrary element or
> slice of such an array, would need some extra info.
>
>
>>>>> Also being able to use bit-fields wider than int.
>>>> For me main gain is reasonably standard syntax for integers bigger
>>>> that 64 bits.
>>>
>>> Standard syntax I guess would be something like int128_t and
>>> int256_t. Such wider integers tend to be powers of two.
>>>
>>> But there are two problems with _BitInt:
>>>
>>> * Any odd sizes are allowed, such as _BitInt(391)
>>
>> Why is that a problem? If you don't want odd-sized types, don't use
>> them.
>
> It is an unnecessary complication. There will be a lot of extra rules
> that maybe partly 'implementation defined', so behaviour may vary. And
> people WILL uses those types because they are there, and likely they
> will be inefficient.
Why? And why do you talk specifically about odd numbers? I can
understand your concern about packing arrays of _BitInts that are not
multiples of 8, though I hope you now understand that it is not the
problem you thought it was. However, I see no reason to suppose that
_BitInt(5) is any more or less "complicated" than _BitInt(6) just
because 5 is an odd number!
A major point of the _BitInt concept is to be able to specify and use
integers of specific explicit sizes in a way that is as implementation
independent as possible. Some aspects of the implementation cannot be
avoided - such as the size of unsigned char and alignment and padding
for storage. But the behaviour of the types is entirely independent of
the implementation. There are no "extra rules" - neither for specific
implementations, nor for specific sizes of _BitInt's.
Efficiency of implementation is, of course, up to the implementation.
But there is absolutely no reason to suppose that working with a _BitInt
of size up to the implementation's maximum integer type is going to be
less efficient than using other types and masking. For larger
_BitInt's, there are different possible implementation strategies with
different pros and cons in regard to efficiency.
>
> What happens when a 391-bit type, even unsigned, overflows? These larger
> types are likely to use a multiple of 64-bits, and for 391 bits will
> need 7 x 64 bits, of which the last word will have 57 bits of padding.
> It's very messy.
>
It is not messy at all. Signed integer overflow is UB, unsigned integer
overflow is wrapping. It's the same as always, and could not be
simpler, clearer or neater.
> Specifying a multiple of 64 bits is better; a power of two even better.
>
You can pick _BitInt sizes as you want - if you want a power of two or
multiple of 64, use that. You get exactly the same overflow behaviour.
>
>>> * There appears to be no upper limit on size, so _BitInt(2997901) is a
>>> valid type
>>
>> The upper limit is specified by the implementation as BITINT_MAXWIDTH, a
>> macro defined in <limits.h>.
>>
>> For gcc 15.2.0 on x86_64, BITINT_MAXWIDTH is 65535 (2**16-1).
>> For clang 21.1.5 it's 8388608 (2**23 bits, 1048576 bytes).
>>
>> clang seems to have some problems with _BitInt(8388608). For example,
>> this program:
>>
>> #include <limits.h>
>>
>> _BitInt(BITINT_MAXWIDTH) n = 42;
>>
>> int main(void) {
>> n *= n;
>> }
>>
>> takes a *long* time to compile with clang. I believe it's generating
>> inline code to do the 8388608 by 8388608 bit multiplication.
>
> Now try it with two disparate sizes.
I think compiler implementations would do well to pick a max width that
is a more realistic for real-world use-cases. (And having 2**16 - 1
instead of 2**16 seems very strange to me.) Even more important for
efficiency is to make a distinction between what sizes work well for
inline code, and what should use more generic library code.
>
>>> So what is the result type of multiplying values of those two types?
>>
>> _BitInt types are exempt from the integer promotion rules (so _BitInt(3)
>> doesn't promote to int), but the usual arithmetic conversions apply.
>> If you multiply values of two _BitInt types, the result is the wider of
>> the two types.
>
> So multiplying even two one-million-bit types could overflow!
>
> Such limits for /fixed-width/ integers are ridiculous.
Um, I think you might want to re-read and re-phrase that. When you have
fixed-width integers, you have a finite range. Try to go beyond that,
and you have arithmetic overflow. There is no alternative for
fixed-width integers. It doesn't matter if your integers are 8-bit or a
million bits. Integer systems that don't have overflow need arbitrary
precision - dynamic allocation for different sizes.
>
> You might say this is no different from defining an array of exactly
> 123,456 elements. But the use-cases are very different.
>
> I starting going into details but I guess you don't care about such
> matters or whether the feature makes much sense.
>
>
I am not sure what you mean by that.
[toc] | [prev] | [next] | [standalone]
| From | Michael S <already5chosen@yahoo.com> |
|---|---|
| Date | 2025-11-24 13:44 +0200 |
| Message-ID | <20251124134441.00004be2@yahoo.com> |
| In reply to | #395402 |
On Mon, 24 Nov 2025 12:17:58 +0100 David Brown <david.brown@hesbynett.no> wrote: > > The proposal is not about saving /memory/. It specifically says that > a _BitInt(N) has the same size and alignment as the smallest basic > type that can contain it, until you get to N greater than 64-bit, in > which they are contained in an array of int64_t. (The reality is a > little more formal, to handle targets that have other sizes of their > basic types.) > That is a bit unfortunate. Compiler support for arrays of 17 to 24bit numbers packed as 3 octet per item would have been handy. And not hard at all for compiler to implement, at least on architectures that has proper support for unaligned access, like x86, POWER, Arm and RISC-V. I certainly have real-world applications that use packed arrays like that. They could have been written in cleaner and less error-prone way if such feature was available. I suppose, packed numeric arrays with 5, 6 or 7 octets per item are also used by some people, although they are probably less common than my case.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2025-11-24 15:02 +0100 |
| Message-ID | <10g1oij$2f8lb$3@dont-email.me> |
| In reply to | #395403 |
On 24/11/2025 12:44, Michael S wrote: > On Mon, 24 Nov 2025 12:17:58 +0100 > David Brown <david.brown@hesbynett.no> wrote: >> >> The proposal is not about saving /memory/. It specifically says that >> a _BitInt(N) has the same size and alignment as the smallest basic >> type that can contain it, until you get to N greater than 64-bit, in >> which they are contained in an array of int64_t. (The reality is a >> little more formal, to handle targets that have other sizes of their >> basic types.) >> > > That is a bit unfortunate. > Compiler support for arrays of 17 to 24bit numbers packed as 3 octet > per item would have been handy. And not hard at all for compiler to > implement, at least on architectures that has proper support for > unaligned access, like x86, POWER, Arm and RISC-V. > > I certainly have real-world applications that use packed arrays like > that. They could have been written in cleaner and less error-prone > way if such feature was available. > > I suppose, packed numeric arrays with 5, 6 or 7 octets per item are also > used by some people, although they are probably less common than my > case. > There may certainly be use-cases for such "packed arrays", but I think that would just add complications to the definitions of _BitInt and require more implementation-specific behaviour. And then someone would insist that they be packed by bit, rather than by byte, and cause all the problems that Bart feared. I think this kind of thing is probably best left to implementation-specific features - just like "packed" attributes and pragmas today. Alternatively, a standardised syntax for detailed control of packing and ordering in structs, arrays, and especially bit-fields, could be developed and added to the standards. I don't see a good reason to handle _BitInt's differently.
[toc] | [prev] | [next] | [standalone]
| From | bart <bc@freeuk.com> |
|---|---|
| Date | 2025-11-24 12:31 +0000 |
| Message-ID | <10g1j7h$2deh9$1@dont-email.me> |
| In reply to | #395402 |
On 24/11/2025 11:17, David Brown wrote: > On 24/11/2025 01:30, bart wrote: >> Saving memory was mentioned. To achieve that means having bitfields >> that may not start at bit 0 of a byte, and may cross byte- or word- >> boundaries. >> > > No, that is incorrect. > > The proposal mentions saving /space/ as relevant in FPGAs - not saving / > memory/. But I was responding to a suggestion here that one use of _BitInts - presumably for ordinary hardware - was to save memory. That's not going to happen if they are simply rounded up to the next power-of-two type. If the purpose is, say, a 17-bit type that wraps past values of 131071, then that sounds like a lot of extra code needed, for something that does not sound that useful. Why modulo 2**17; why not 100,000? Or any value more relevant to the task. > The authors use-case here is in writing code that can be > compiled with a "normal" C compiler on a "normal" target, and also > compiled to FPGA /hardware/, with the same semantics. In hardware, a 5- > bit by 5-bit single-cycle multiplier is very much smaller than an 8-bit > by 8-bit multiplier, and orders of magnitude smaller than if the 5-bit > integers are promoted to 32-bit before multiplying. > > The proposal is not about saving /memory/. It specifically says that a > _BitInt(N) has the same size and alignment as the smallest basic type > that can contain it, until you get to N greater than 64-bit, in which > they are contained in an array of int64_t. (The reality is a little > more formal, to handle targets that have other sizes of their basic types.) > > So on a "normal" target, a _BitInt(3) is the same size and alignment as > a uint8_t, a _BitInt(35) is effectively contained in an uint64_t, and an > array of 4 _BitInt(17) on a 32-bit system will take 16 bytes or 128 > bits, not 68 bits. > As far as I can see, the C23 standard does not specify these details, > and leaves them up to the target ABI. But at the very least, they will > always take an integer number of bytes - unsigned char. There can never > be any crossing of byte boundaries. What about arrays of _BitInt(1), _BitInt(2) and _BitInt(4)? These could actually be practically implemented, with a few restrictions, and could save a lot of memory. > Why? And why do you talk specifically about odd numbers? I can > understand your concern about packing arrays of _BitInts that are not > multiples of 8, though I hope you now understand that it is not the > problem you thought it was. However, I see no reason to suppose that > _BitInt(5) is any more or less "complicated" than _BitInt(6) just > because 5 is an odd number! I mean odd compared with powers-of-two, or multiples of 8. > > A major point of the _BitInt concept is to be able to specify and use > integers of specific explicit sizes in a way that is as implementation > independent as possible. Some aspects of the implementation cannot be > avoided - such as the size of unsigned char and alignment and padding > for storage. But the behaviour of the types is entirely independent of > the implementation. There are no "extra rules" - neither for specific > implementations, nor for specific sizes of _BitInt's. > > Efficiency of implementation is, of course, up to the implementation. > But there is absolutely no reason to suppose that working with a _BitInt > of size up to the implementation's maximum integer type is going to be > less efficient than using other types and masking. For larger > _BitInt's, there are different possible implementation strategies with > different pros and cons in regard to efficiency. > >> >> What happens when a 391-bit type, even unsigned, overflows? These >> larger types are likely to use a multiple of 64-bits, and for 391 bits >> will need 7 x 64 bits, of which the last word will have 57 bits of >> padding. It's very messy. >> > > It is not messy at all. Signed integer overflow is UB, unsigned integer > overflow is wrapping. It's the same as always, and could not be > simpler, clearer or neater. In my 391-bit example, the top 7 bits will be within a 64-bit word. What values will those extra 57 bits be? Taking just those 7 bits by themselves, if the value is 1111111, that is: 00000000'00000000'00000000'00000000'00000000'00000000'00000000'01111111) and you do an arithmetic right shift, then you will get 0111111 not 1111111, since the hardware sign bit is bit 63 not bit 6. It needs more work. >> Such limits for /fixed-width/ integers are ridiculous. > > Um, I think you might want to re-read and re-phrase that. When you have > fixed-width integers, you have a finite range. No, I stand by it. There are even different levels of ridiculousness: expecting a language to support a huge fixed integer type like int1000000_t (when C only acquired 8/16/32/64-bit types in C99, and those still aren't built-in). And allowing random sizes such as int817838_t. (See, it seems much sillier using this syntax!) For such sizes it makes much more sense to acknowledge the existence of arbitrary-precision support, so that the equivalents of int1000000_t and int817838_t would be compatible types. Or you can forget specific widths and just have the one bigint type. (I use such types, but within a library, and there there are ways cap the precision.)
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2025-11-24 05:33 -0800 |
| Message-ID | <87y0nv369c.fsf@example.invalid> |
| In reply to | #395408 |
bart <bc@freeuk.com> writes:
> On 24/11/2025 11:17, David Brown wrote:
>> On 24/11/2025 01:30, bart wrote:
>>> Saving memory was mentioned. To achieve that means having bitfields
>>> that may not start at bit 0 of a byte, and may cross byte- or word-
>>> boundaries.
>>>
>> No, that is incorrect.
>> The proposal mentions saving /space/ as relevant in FPGAs - not
>> saving / memory/.
>
> But I was responding to a suggestion here that one use of _BitInts -
> presumably for ordinary hardware - was to save memory.
That's *your* presumption.
The rationale section of N2709 mentions performance/space concerns only
in the context of FPGAs.
Packing arrays on ordinary hardware is impractical given C's memory
model.
[...]
> What about arrays of _BitInt(1), _BitInt(2) and _BitInt(4)? These
> could actually be practically implemented, with a few restrictions,
> and could save a lot of memory.
No, they couldn't. Array indexing is defined in terms of pointer
arithmetic, and you can't have a pointer to something smaller than one
byte.
<OT>I can see something this being done in C++ with operator
overloading. See, for example, the std::vector<bool> partial
specialization.</OT>
[...]
> In my 391-bit example, the top 7 bits will be within a 64-bit
> word. What values will those extra 57 bits be?
Probably 0.
> Taking just those 7 bits by themselves, if the value is 1111111, that is:
> 00000000'00000000'00000000'00000000'00000000'00000000'00000000'01111111)
>
> and you do an arithmetic right shift, then you will get 0111111 not
>
> 1111111, since the hardware sign bit is bit 63 not bit 6. It needs
> more work.
Yes, the compiler has to do some extra work for types with padding bits,
to ensure that those bits are either set to 0 or properly ignored.
[...]
> No, I stand by it. There are even different levels of ridiculousness:
> expecting a language to support a huge fixed integer type like
> int1000000_t (when C only acquired 8/16/32/64-bit types in C99, and
> those still aren't built-in).
>
> And allowing random sizes such as int817838_t. (See, it seems much
> sillier using this syntax!)
Your complaint seems to be that the feature is too flexible.
> For such sizes it makes much more sense to acknowledge the existence
> of arbitrary-precision support, so that the equivalents of
> int1000000_t and int817838_t would be compatible types. Or you can
> forget specific widths and just have the one bigint type.
Yes, there are a lot of things that C23 *could* have done, but 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]
| From | bart <bc@freeuk.com> |
|---|---|
| Date | 2025-11-24 14:41 +0000 |
| Message-ID | <10g1qpu$2fi66$2@dont-email.me> |
| In reply to | #395415 |
On 24/11/2025 13:33, Keith Thompson wrote:
> bart <bc@freeuk.com> writes:
>> What about arrays of _BitInt(1), _BitInt(2) and _BitInt(4)? These
>> could actually be practically implemented, with a few restrictions,
>> and could save a lot of memory.
>
> No, they couldn't. Array indexing is defined in terms of pointer
> arithmetic, and you can't have a pointer to something smaller than one
> byte.
The restrictions I mentioned were to do with pointers to individual bits.
It is possible that operations such as:
x = A[i]
A[i] = x
can be well defined when A is an array of 1/2/4-bit values, even if
expressed like this:
*(A + i)
But this would have to be indivisible when A is such an array: only the
whole thing is valid, not (A + i) by itself, or A by itself; you'd need &A.
This would need a small tweak to the language, but that is nothing
compared to supporting (i3783467 * i999 / i3) >> i17.
But I write a script in my dynamic language, which does support arrays
of 'u1 u2 u4', and it gives these results:
Array of u1 uses 12,500,000 bytes
Array of u2 uses 25,000,000 bytes
Array of u4 uses 50,000,000 bytes
Array of u8 uses 100,000,000 bytes
Array of u16 uses 200,000,000 bytes
Array of u32 uses 400,000,000 bytes
Array of u64 uses 800,000,000 bytes
C can only get down to that u8 figure (100MB) using its 'char' type.
Even 'bool' doesn't make it smaller (presumably for the reasons you
mentioned).
You are forced to emulate such arrays in user-code using shifts and masks.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2025-11-24 16:46 -0800 |
| Message-ID | <87pl972b2v.fsf@example.invalid> |
| In reply to | #395421 |
bart <bc@freeuk.com> writes:
> On 24/11/2025 13:33, Keith Thompson wrote:
>> bart <bc@freeuk.com> writes:
>
>>> What about arrays of _BitInt(1), _BitInt(2) and _BitInt(4)? These
>>> could actually be practically implemented, with a few restrictions,
>>> and could save a lot of memory.
>> No, they couldn't. Array indexing is defined in terms of pointer
>> arithmetic, and you can't have a pointer to something smaller than one
>> byte.
>
> The restrictions I mentioned were to do with pointers to individual bits.
Right. C doesn't have pointers to individual bits.
> It is possible that operations such as:
>
> x = A[i]
> A[i] = x
>
> can be well defined when A is an array of 1/2/4-bit values, even if
> expressed like this:
>
> *(A + i)
Not in C as it's currently defined.
> But this would have to be indivisible when A is such an array: only
> the whole thing is valid, not (A + i) by itself, or A by itself; you'd
> need &A.
>
> This would need a small tweak to the language, but that is nothing
> compared to supporting (i3783467 * i999 / i3) >> i17.
It would hardly be a "small tweak".
I can imagine some future version of C adding support for indexing
packed arrays, but I don't think it would have been worthwhile
just so that large arrays of small _BitInts can be stored more
efficiently. Doing that on ordinary hardware was not part of the
rationale for C23's bit-precise integer types, and I haven't seen
any such proposals for C2y.
And assuming that "(i3783467 * i999 / i3) >> i17" means what I think
it means, huge bit-precise integers are already standard (they're
part of C23), and the work of implementing them is largely done in
gcc and llvm/clang.
> But I write a script in my dynamic language,
[...]
> C can only get down to that u8 figure (100MB) using its 'char'
> type. Even 'bool' doesn't make it smaller (presumably for the reasons
> you mentioned).
>
> You are forced to emulate such arrays in user-code using shifts and masks.
Yes. C doesn't support packed arrays, and is unlikely to do so
any time in the near future. C23 added a feature that doesn't do
everything you want it to do. You can of course implement such
things in a library, but the syntax for using it would probably be
a bit ugly.
And in fact at least one person has done so. (I've known about
this for about a minute, so I have no comment other than that
it exists.)
https://github.com/gpakosz/PackedArray/
--
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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2025-11-24 15:41 +0100 |
| Message-ID | <10g1qq9$2f8lb$4@dont-email.me> |
| In reply to | #395408 |
On 24/11/2025 13:31, bart wrote: > On 24/11/2025 11:17, David Brown wrote: >> On 24/11/2025 01:30, bart wrote: > >>> Saving memory was mentioned. To achieve that means having bitfields >>> that may not start at bit 0 of a byte, and may cross byte- or word- >>> boundaries. >>> >> >> No, that is incorrect. >> >> The proposal mentions saving /space/ as relevant in FPGAs - not saving >> / memory/. > > But I was responding to a suggestion here that one use of _BitInts - > presumably for ordinary hardware - was to save memory. > OK. However, that is not what is in the proposal, nor in the C23 standard. > That's not going to happen if they are simply rounded up to the next > power-of-two type. Correct (with the proviso that after 64 bits, rounding is to whatever type can contain an int64_t). As I mentioned, I don't think the C standards require that rounding-up size, even though it was in the proposal. It may be worth punting that question over to the "comp.std.c" newsgroup to see if someone has a definite answer. For the kind of small systems that had been mentioned in the context of saving memory, compilers often have extensions or implementation-specific features (attributes, pragmas, etc.) to go beyond standard C in order to get greater efficiency on tiny systems. These may support smaller containers or tighter array packing. > > If the purpose is, say, a 17-bit type that wraps past values of 131071, > then that sounds like a lot of extra code needed, for something that > does not sound that useful. Why modulo 2**17; why not 100,000? Or any > value more relevant to the task. > Signed _BitInt's don't wrap - arithmetic overflow is UB. Unsigned _BitInt's wrap, just like with all other unsigned integer types in C. And wrapping is /not/ a lot of extra code - wrapping an N-bit type is just a and instruction with the constant (2 << N) - 1. This can be done once at the end of complex arithmetic expressions, in most cases (shift-right and division can mean extra masking is needed). Why not provide wrapping types with arbitrary wrapping values? Why not indeed - some languages do (Ada springs to mind). They are not actually that often needed, so it's easier just to put a "% X" operation in the user code. The rational in the proposal that you linked said why these _BitInt types can be useful. They are for expressing the intent of the programmer more clearly, making it more convenient to work with somewhat bigger integer sizes (such as for cryptography), and improving FPGA development. Wrapping is not a big point (and it does not apply at all to signed _BitInt). > >> The authors use-case here is in writing code that can be compiled >> with a "normal" C compiler on a "normal" target, and also compiled to >> FPGA /hardware/, with the same semantics. In hardware, a 5- bit by >> 5-bit single-cycle multiplier is very much smaller than an 8-bit by >> 8-bit multiplier, and orders of magnitude smaller than if the 5-bit >> integers are promoted to 32-bit before multiplying. >> >> The proposal is not about saving /memory/. It specifically says that >> a _BitInt(N) has the same size and alignment as the smallest basic >> type that can contain it, until you get to N greater than 64-bit, in >> which they are contained in an array of int64_t. (The reality is a >> little more formal, to handle targets that have other sizes of their >> basic types.) >> >> So on a "normal" target, a _BitInt(3) is the same size and alignment >> as a uint8_t, a _BitInt(35) is effectively contained in an uint64_t, >> and an array of 4 _BitInt(17) on a 32-bit system will take 16 bytes or >> 128 bits, not 68 bits. > >> As far as I can see, the C23 standard does not specify these details, >> and leaves them up to the target ABI. But at the very least, they >> will always take an integer number of bytes - unsigned char. There >> can never be any crossing of byte boundaries. > > What about arrays of _BitInt(1), _BitInt(2) and _BitInt(4)? These could > actually be practically implemented, with a few restrictions, and could > save a lot of memory. > They could - but that would add a lot of complications (the once you worried about). I would assume that this was considered both by the authors of the proposal, and by the C committee, and rejected as not being worth the cost. >> Why? And why do you talk specifically about odd numbers? I can >> understand your concern about packing arrays of _BitInts that are not >> multiples of 8, though I hope you now understand that it is not the >> problem you thought it was. However, I see no reason to suppose that >> _BitInt(5) is any more or less "complicated" than _BitInt(6) just >> because 5 is an odd number! > > I mean odd compared with powers-of-two, or multiples of 8. Okay. "Unusual" might have been a better choice of term, or you could have explained what you meant. But that makes more sense. > >> >> A major point of the _BitInt concept is to be able to specify and use >> integers of specific explicit sizes in a way that is as implementation >> independent as possible. Some aspects of the implementation cannot be >> avoided - such as the size of unsigned char and alignment and padding >> for storage. But the behaviour of the types is entirely independent >> of the implementation. There are no "extra rules" - neither for >> specific implementations, nor for specific sizes of _BitInt's. >> >> Efficiency of implementation is, of course, up to the implementation. >> But there is absolutely no reason to suppose that working with a >> _BitInt of size up to the implementation's maximum integer type is >> going to be less efficient than using other types and masking. For >> larger _BitInt's, there are different possible implementation >> strategies with different pros and cons in regard to efficiency. >> >>> >>> What happens when a 391-bit type, even unsigned, overflows? These >>> larger types are likely to use a multiple of 64-bits, and for 391 >>> bits will need 7 x 64 bits, of which the last word will have 57 bits >>> of padding. It's very messy. >>> >> >> It is not messy at all. Signed integer overflow is UB, unsigned >> integer overflow is wrapping. It's the same as always, and could not >> be simpler, clearer or neater. > > In my 391-bit example, the top 7 bits will be within a 64-bit word. What > values will those extra 57 bits be? > They are padding bits. They don't contribute to the value of the object. An implementation, or rather an ABI, can decide that they should always be zero, or always zero for unsigned _BitInt and always a sign extension for signed _BitInt, or it can decide that they are always ignored. Giving a specific value means masking may be needed before storing a value in memory or passing it on to an external function, while making it ignored can mean masking might be needed when reading from memory or using a returned value. It is not really any different from other padding bits or bytes, such as all but the LSB in a _Bool, or padding in structs. > Taking just those 7 bits by themselves, if the value is 1111111, that is: > 00000000'00000000'00000000'00000000'00000000'00000000'00000000'01111111) > > and you do an arithmetic right shift, then you will get 0111111 not C does not have an "arithmetic right shift" operation - that's an assembly-level operation. Signed right-shift of negative values is implementation-defined in C. > > 1111111, since the hardware sign bit is bit 63 not bit 6. It needs more > work. > If the value of those 7 bits is 0111'1111, you have a negative value and right-shifting that is implementation-defined. The compiler implementation can pick whatever it feels is efficient and a good choice for its users. Maybe that means it defines the right-shift to work as though the type was unsigned - you get 0011'1111. Maybe it means it defines the padding bits for signed _BitInt to use sign extension, and signed right-shift instructions. Maybe it means that the compiler will mask the value, then sign-extend it, then do a signed right-shift instruction, then mask it again. That's all up to the implementation. You are worrying about completely negligible things here. (If you are considering adding support for _BitInt to your own C tools, then I understand wanting to get all the details right.) > >>> Such limits for /fixed-width/ integers are ridiculous. >> >> Um, I think you might want to re-read and re-phrase that. When you >> have fixed-width integers, you have a finite range. > > No, I stand by it. There are even different levels of ridiculousness: > expecting a language to support a huge fixed integer type like > int1000000_t (when C only acquired 8/16/32/64-bit types in C99, and > those still aren't built-in). > > And allowing random sizes such as int817838_t. (See, it seems much > sillier using this syntax!) I had taken your "ridiculous" comment to be part of your complaint that "multiplying even two one-million-bit types could overflow". But those statements are independent, then only the first is silly - of course arithmetic on any finite sized type can overflow unless specifically limited (such as by wrapping behaviour for unsigned types). I agree that huge fixed-size integer types are not useful, though I am not sure where the ideal limit lies. The biggest use-case for very large integers is cryptography. I find it hard to imagine sizes greater than 16 kbit being directly useful, and thus 32 kbit sizes for intermediary results. Fixed sizes can be more efficient than arbitrary precision types when the same sized objects are used repeatedly. > > For such sizes it makes much more sense to acknowledge the existence of > arbitrary-precision support, so that the equivalents of int1000000_t and > int817838_t would be compatible types. Or you can forget specific widths > and just have the one bigint type. > > (I use such types, but within a library, and there there are ways cap > the precision.) > > >
[toc] | [prev] | [next] | [standalone]
| From | bart <bc@freeuk.com> |
|---|---|
| Date | 2025-11-24 18:35 +0000 |
| Message-ID | <10g28gm$2mf9s$1@dont-email.me> |
| In reply to | #395422 |
On 24/11/2025 14:41, David Brown wrote: > On 24/11/2025 13:31, bart wrote: > That's all up to the implementation. > > You are worrying about completely negligible things here. Is it that negligible? That's easy to say when you're not doing the implementing! However it may impact on the size and performance of code. >> And allowing random sizes such as int817838_t. (See, it seems much >> sillier using this syntax!) > > I had taken your "ridiculous" comment to be part of your complaint that > "multiplying even two one-million-bit types could overflow". But those > statements are independent, then only the first is silly - of course > arithmetic on any finite sized type can overflow unless specifically > limited (such as by wrapping behaviour for unsigned types). I agree > that huge fixed-size integer types are not useful, though I am not sure > where the ideal limit lies. You don't think it strange that C doesn't even have a 128-bit type yet (it only barely has width-specific 64-bit ones). There is just the poor gnu extension where 128-bit integers didn't have a literal form, and there was no way to print such values. But now there is this huge leap, not only to 128/256/512/1024 bits, but to conceivably millions, plus the ability to specify any weird type you like, like 182 bits (eg. somebody makes a typo for _BitInt(128), but they silently get a viable type that happens to be a little less efficient!). So, 20 years of having 64-bit processors with little or no support for even double-word types, and now there is this explosion in capabilities. Or, are literals and print facilities for these new types still missing? Personally I think they should have got the basics right first, like a decent 128-bit type, proper literals, and ways to print. This looks like VLAs all over again (eg. is '_BitInt(1000000) A' allocated on the stack?). A poorly suited, hard-to-implement feature.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2025-11-24 21:26 +0100 |
| Message-ID | <10g2f2d$2oufq$1@dont-email.me> |
| In reply to | #395428 |
On 24/11/2025 19:35, bart wrote:
> On 24/11/2025 14:41, David Brown wrote:
>> On 24/11/2025 13:31, bart wrote:
>
>> That's all up to the implementation.
>>
>> You are worrying about completely negligible things here.
>
> Is it that negligible? That's easy to say when you're not doing the
> implementing!
Of course I am not implementing it. As always with features in C, no
one is particularly bothered about how much effort is needed by the
implementers. The prime concern is always the compiler users, not the
compiler writers.
> However it may impact on the size and performance of code.
The impact of an extra mask operation when you are handling 6 (IIRC)
chunks of 64-bit data is not going to give a very significant effect on
the size or performance of the code.
>
>
>>> And allowing random sizes such as int817838_t. (See, it seems much
>>> sillier using this syntax!)
>>
>> I had taken your "ridiculous" comment to be part of your complaint
>> that "multiplying even two one-million-bit types could overflow". But
>> those statements are independent, then only the first is silly - of
>> course arithmetic on any finite sized type can overflow unless
>> specifically limited (such as by wrapping behaviour for unsigned
>> types). I agree that huge fixed-size integer types are not useful,
>> though I am not sure where the ideal limit lies.
>
> You don't think it strange that C doesn't even have a 128-bit type yet
> (it only barely has width-specific 64-bit ones).
How do you that I think that, from what I wrote? You are just making
stuff up again.
I think a 128-bit type can be useful. Many C compilers support one, and
now the standard supports one too. It's called "_BitInt(128)", and you
can expect it to perform exactly like __int128 or whatever
compiler-specific 128-bit types you might have in a given tool.
>
> There is just the poor gnu extension where 128-bit integers didn't have
> a literal form, and there was no way to print such values.
>
How many times have you felt the need to write a 128-bit literal? And
how many times has that literal been in decimal (it's not difficult to
put together a 128-bit value from two 64-bit values)? You really are
making a mountain out of a molehill here.
> But now there is this huge leap, not only to 128/256/512/1024 bits, but
> to conceivably millions, plus the ability to specify any weird type you
> like, like 182 bits (eg. somebody makes a typo for _BitInt(128), but
> they silently get a viable type that happens to be a little less
> efficient!).
>
And this huge leap also lets you have 128-bit, 256-bit, 512-bit, etc.,
types with no more than a simple typedef if you don't like the names. I
can't see your problem here.
> So, 20 years of having 64-bit processors with little or no support for
> even double-word types, and now there is this explosion in capabilities.
>
> Or, are literals and print facilities for these new types still missing?
>
> Personally I think they should have got the basics right first, like a
> decent 128-bit type, proper literals, and ways to print.
>
> This looks like VLAs all over again (eg. is '_BitInt(1000000) A'
> allocated on the stack?). A poorly suited, hard-to-implement feature.
>
You are joking, right? How is dealing with a _BitInt(1000000) any more
difficult than dealing with a "struct { uint64_t chunks[125000]; }" ?
[toc] | [prev] | [next] | [standalone]
Page 2 of 13 — ← Prev page 1 [2] 3 4 … 13 Next page →
Back to top | Article view | comp.lang.c
csiph-web