Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #402780 > unrolled thread
| Started by | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| First post | 2026-10-06 23:08 -0700 |
| Last post | 2026-10-13 03:52 -0700 |
| Articles | 20 on this page of 96 — 20 participants |
Back to article view | Back to comp.lang.c
AVL tree insertion - programming exercise Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-10-06 23:08 -0700
Re: AVL tree insertion - programming exercise fir <profesor.fir@gmail.com> - 2026-10-07 15:25 +0200
Re: AVL tree insertion - programming exercise Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-10-07 12:13 -0700
Re: AVL tree insertion - programming exercise fir <profesor.fir@gmail.com> - 2026-10-07 21:28 +0200
Re: AVL tree insertion - programming exercise Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-10-08 05:31 -0700
Re: AVL tree insertion - programming exercise fir <profesor.fir@gmail.com> - 2026-10-09 11:12 +0200
Re: AVL tree insertion - programming exercise fir <profesor.fir@gmail.com> - 2026-10-09 11:12 +0200
Re: AVL tree insertion - programming exercise BGB <cr88192@gmail.com> - 2026-10-07 20:10 -0500
Re: AVL tree insertion - programming exercise Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-10-08 05:56 -0700
Re: AVL tree insertion - programming exercise BGB <cr88192@gmail.com> - 2026-10-08 15:09 -0500
Re: AVL tree insertion - programming exercise fir <profesor.fir@gmail.com> - 2026-10-08 22:56 +0200
Re: AVL tree insertion - programming exercise BGB <cr88192@gmail.com> - 2026-10-08 17:29 -0500
Re: AVL tree insertion - programming exercise fir <profesor.fir@gmail.com> - 2026-10-09 09:56 +0200
Re: AVL tree insertion - programming exercise Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-10-09 01:39 +0200
Re: AVL tree insertion - programming exercise Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-10-09 00:03 -0700
Re: AVL tree insertion - programming exercise Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-10-08 23:53 -0700
Re: AVL tree insertion - programming exercise David Brown <david.brown@hesbynett.no> - 2026-10-09 10:34 +0200
Re: AVL tree insertion - programming exercise Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-10-09 12:27 +0200
Re: AVL tree insertion - programming exercise David Brown <david.brown@hesbynett.no> - 2026-10-09 12:59 +0200
Re: AVL tree insertion - programming exercise bart <bc@freeuk.com> - 2026-10-09 11:43 +0100
Re: AVL tree insertion - programming exercise David Brown <david.brown@hesbynett.no> - 2026-10-09 13:20 +0200
Re: AVL tree insertion - programming exercise cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-09 12:38 +0000
Re: AVL tree insertion - programming exercise David Brown <david.brown@hesbynett.no> - 2026-10-09 16:05 +0200
Re: AVL tree insertion - programming exercise Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-10-09 17:54 +0200
Re: AVL tree insertion - programming exercise Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-10-10 10:38 +0800
Re: AVL tree insertion - programming exercise ram@zedat.fu-berlin.de (Stefan Ram) - 2026-10-10 03:12 +0000
Re: AVL tree insertion - programming exercise Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-10-10 04:44 +0000
Re: AVL tree insertion - programming exercise "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-10-10 14:12 -0700
Re: AVL tree insertion - programming exercise cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-09 19:48 +0000
Re: AVL tree insertion - programming exercise scott@slp53.sl.home (Scott Lurndal) - 2026-10-09 23:18 +0000
Re: AVL tree insertion - programming exercise David Brown <david.brown@hesbynett.no> - 2026-10-10 15:27 +0200
Re: AVL tree insertion - programming exercise cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-12 18:26 +0000
Re: AVL tree insertion - programming exercise David Brown <david.brown@hesbynett.no> - 2026-10-12 21:17 +0200
Re: AVL tree insertion - programming exercise Michael S <already5chosen@yahoo.com> - 2026-10-09 17:47 +0300
Re: AVL tree insertion - programming exercise cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-09 16:48 +0000
Re: AVL tree insertion - programming exercise Michael S <already5chosen@yahoo.com> - 2026-10-10 19:08 +0300
Re: AVL tree insertion - programming exercise David Brown <david.brown@hesbynett.no> - 2026-10-10 18:29 +0200
Re: AVL tree insertion - programming exercise cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-10 17:44 +0000
Re: AVL tree insertion - programming exercise David Brown <david.brown@hesbynett.no> - 2026-10-10 23:22 +0200
Re: AVL tree insertion - programming exercise cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-10 17:43 +0000
Re: AVL tree insertion - programming exercise Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-10-10 20:35 +0200
Re: AVL tree insertion - programming exercise cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-10 19:36 +0000
Re: AVL tree insertion - programming exercise Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-10-10 22:08 +0200
Re: AVL tree insertion - programming exercise Michael S <already5chosen@yahoo.com> - 2026-10-10 23:21 +0300
Re: AVL tree insertion - programming exercise cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-10 20:55 +0000
Re: AVL tree insertion - programming exercise scott@slp53.sl.home (Scott Lurndal) - 2026-10-10 20:22 +0000
Re: AVL tree insertion - programming exercise Michael S <already5chosen@yahoo.com> - 2026-10-10 23:32 +0300
Re: AVL tree insertion - programming exercise scott@slp53.sl.home (Scott Lurndal) - 2026-10-11 15:24 +0000
Re: AVL tree insertion - programming exercise Bonita Montero <Bonita.Montero@gmail.com> - 2026-10-10 19:40 +0200
Re: AVL tree insertion - programming exercise Andrey Tarasevich <noone@noone.net> - 2026-10-10 12:39 -0700
Re: AVL tree insertion - programming exercise Michael S <already5chosen@yahoo.com> - 2026-10-10 23:00 +0300
Re: AVL tree insertion - programming exercise Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-10-10 22:28 +0200
Re: AVL tree insertion - programming exercise Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-10-10 19:02 -0700
Re: AVL tree insertion - programming exercise "chine.bleu" <chine.bleu@yahoo.com> - 2026-10-13 01:38 -0700
Re: AVL tree insertion - programming exercise David Brown <david.brown@hesbynett.no> - 2026-10-13 11:42 +0200
Re: AVL tree insertion - programming exercise cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-13 10:55 +0000
Re: AVL tree insertion - programming exercise Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-10-13 04:29 -0700
Re: AVL tree insertion - programming exercise David Brown <david.brown@hesbynett.no> - 2026-10-13 14:01 +0200
Re: AVL tree insertion - programming exercise Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-10-13 05:09 -0700
Re: AVL tree insertion - programming exercise antispam@fricas.org (Waldek Hebisch) - 2026-10-13 19:01 +0000
Re: AVL tree insertion - programming exercise cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-13 15:17 +0000
Re: AVL tree insertion - programming exercise David Brown <david.brown@hesbynett.no> - 2026-10-13 17:39 +0200
Re: AVL tree insertion - programming exercise Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-10-13 09:01 -0700
Re: AVL tree insertion - programming exercise cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-13 21:17 +0000
Re: AVL tree insertion - programming exercise "chine.bleu" <chine.bleu@yahoo.com> - 2026-10-13 18:01 -0700
Re: AVL tree insertion - programming exercise Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-10-13 21:13 -0700
Re: AVL tree insertion - programming exercise David Brown <david.brown@hesbynett.no> - 2026-10-14 09:43 +0200
Re: AVL tree insertion - programming exercise cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-14 20:11 +0000
Re: AVL tree insertion - programming exercise Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-10-14 15:25 -0700
Re: AVL tree insertion - programming exercise David Brown <david.brown@hesbynett.no> - 2026-10-15 09:28 +0200
Re: AVL tree insertion - programming exercise cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-14 14:13 +0000
Re: AVL tree insertion - programming exercise Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-10-14 18:03 +0200
Re: AVL tree insertion - programming exercise cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-14 18:21 +0000
Re: AVL tree insertion - programming exercise Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-10-14 15:42 -0700
Re: AVL tree insertion - programming exercise cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-15 14:25 +0000
Re: AVL tree insertion - programming exercise Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-10-15 15:54 -0700
Re: AVL tree insertion - programming exercise Kaz Kylheku <046-301-5902@kylheku.com> - 2026-10-15 23:51 +0000
Re: AVL tree insertion - programming exercise Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-10-15 18:14 -0700
Re: AVL tree insertion - programming exercise cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-16 03:09 +0000
Re: AVL tree insertion - programming exercise Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-10-15 21:34 -0700
Re: AVL tree insertion - programming exercise cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-16 11:27 +0000
Re: AVL tree insertion - programming exercise Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-10-14 10:39 -0700
Re: AVL tree insertion - programming exercise scott@slp53.sl.home (Scott Lurndal) - 2026-10-13 17:15 +0000
Re: AVL tree insertion - programming exercise cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-13 21:30 +0000
Re: AVL tree insertion - programming exercise "chine.bleu" <chine.bleu@yahoo.com> - 2026-10-13 08:19 -0700
Re: AVL tree insertion - programming exercise "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-10-13 13:16 -0700
Re: AVL tree insertion - programming exercise Michael S <already5chosen@yahoo.com> - 2026-10-13 23:28 +0300
Re: AVL tree insertion - programming exercise James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-10-13 06:20 -0400
Re: AVL tree insertion - programming exercise cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-13 14:34 +0000
Re: AVL tree insertion - programming exercise Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-10-13 20:45 -0700
Re: AVL tree insertion - programming exercise cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-14 14:25 +0000
Re: AVL tree insertion - programming exercise Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-10-14 20:54 -0700
Re: AVL tree insertion - programming exercise Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-10-14 22:47 -0700
Re: AVL tree insertion - programming exercise Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-10-15 04:42 -0700
Re: AVL tree insertion - programming exercise "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-10-15 14:07 -0700
Re: AVL tree insertion - programming exercise Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-10-13 03:52 -0700
Page 4 of 5 — ← Prev page 1 2 3 [4] 5 Next page →
| From | cross@spitfire.i.gajendra.net (Dan Cross) |
|---|---|
| Date | 2026-10-13 15:17 +0000 |
| Message-ID | <11ali2e$pi$1@reader2.panix.com> |
| In reply to | #403096 |
In article <11al4mu$fqtl$1@kst.eternal-september.org>, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote: >David Brown <david.brown@hesbynett.no> writes: >> On 13/10/2026 10:38, chine.bleu wrote: >>> Tim Rentsch wrote: >>>> sons[2] array. These links are basically pointers, but held >>>> as uintptr_t so they can take one of the bits to mean "tall", >>>> which means taller than the other subtree of the node. The >>>> tree structure should maintain an invariant that at most one >>> Memory is cheap. >> >> Not any more! >> >>> Do not encode tags into low bits of an address unless you really >>> know what your doing. >> >> Agreed, as a principle. >> >>> As a precaution check the return address of malloc >>> p = malloc(m); >>> if ((uintptr_t)p)&1!=0) abort(); >> >> malloc always returns an address with suitable alignment for any >> fundamental alignment on the target. I don't think this is true anymore, as of C23. Here's the relevant text from n3220, sec 7.24.3, describing the return value from `malloc` et al: |The pointer returned if the allocation succeeds is suitably |aligned so that it may be assigned to a pointer to any type of |object with a fundamental alignment requirement and size less |than or equal to the size requested. This sentence is somewhat ambiguous because it's unclear whether the "less than or equal to the size requested" criteria applies to both the pointer type's size _and_ fundamental alignment requirement, or _just_ the size, but I believe that it is the former (that is, the "and" applies the size requirement to both alignment and returned size). Thus, a conforming implementation of `malloc(1)` could return a pointer that is `alignof(char)`, but not `alignof(int)`. I argue that examining the text from C17 and how it has changed further supports this interpretation. From C17, sec 7.22.3: |The pointer returned if the allocation succeeds is suitably |aligned so that it may be assigned to a pointer to any type of |object with a fundamental alignment requirement and then used |to access such an object or an array of such objects in the |space allocated (until the space is explicitly deallocated). Here, no mention of the requested size is made at all, and this clearly requires the return value from a successful allocation by `malloc(1)` to be aligned so that one could assign it to a pointer referring to any object of any type with a "fundamental alignment requirement." >> Typically that means at least >> 64-bit alignment (and thus the three LSB's are always zero), but it is >> implementation dependent. > >Typically yes, but the standard says nearly nothing about how >pointers are represented. If your assume a 64-bit aligned pointer >has zeros in the 3 LSBs, it's at least potentionally non-portable. >(The systems I've used that broke that assumption are most likely >no longer in use.) This. It's unlikely that any real world system will do anything differently these >Another possible issue appear if you're using garbage collection. >If you alter the low bits of a pointer, you might clobber the only >live reference to the object it points to, and the garbage collector >might deallocate it behind your back. > >Perhaps more realistically, by *not* playing games with pointer >representations, you'll have one less thing to worry about when >tracking down why your code is mysteriously misbehaving. Playing games with pointer values can be useful for implementing things like, e.g, Harris's lock-free linked list. - Dan C.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2026-10-13 17:39 +0200 |
| Message-ID | <11aljb2$j7bi$1@dont-email.me> |
| In reply to | #403106 |
On 13/10/2026 17:17, Dan Cross wrote: > In article <11al4mu$fqtl$1@kst.eternal-september.org>, > Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote: >> David Brown <david.brown@hesbynett.no> writes: >>> On 13/10/2026 10:38, chine.bleu wrote: >>>> Tim Rentsch wrote: >>>>> sons[2] array. These links are basically pointers, but held >>>>> as uintptr_t so they can take one of the bits to mean "tall", >>>>> which means taller than the other subtree of the node. The >>>>> tree structure should maintain an invariant that at most one >>>> Memory is cheap. >>> >>> Not any more! >>> >>>> Do not encode tags into low bits of an address unless you really >>>> know what your doing. >>> >>> Agreed, as a principle. >>> >>>> As a precaution check the return address of malloc >>>> p = malloc(m); >>>> if ((uintptr_t)p)&1!=0) abort(); >>> >>> malloc always returns an address with suitable alignment for any >>> fundamental alignment on the target. > > I don't think this is true anymore, as of C23. Here's the > relevant text from n3220, sec 7.24.3, describing the return > value from `malloc` et al: > > |The pointer returned if the allocation succeeds is suitably > |aligned so that it may be assigned to a pointer to any type of > |object with a fundamental alignment requirement and size less > |than or equal to the size requested. > > This sentence is somewhat ambiguous because it's unclear whether > the "less than or equal to the size requested" criteria applies > to both the pointer type's size _and_ fundamental alignment > requirement, or _just_ the size, but I believe that it is the > former (that is, the "and" applies the size requirement to both > alignment and returned size). Thus, a conforming implementation > of `malloc(1)` could return a pointer that is `alignof(char)`, > but not `alignof(int)`. > Your interpretation seems sound to me. (I looked at the C11 standards when I made my earlier post - it had not occurred to me that C23 might have changed the wording here. The change is not mentioned in the change history, as far as I can see.)
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2026-10-13 09:01 -0700 |
| Message-ID | <86v775h9o2.fsf@linuxsc.com> |
| In reply to | #403106 |
cross@spitfire.i.gajendra.net (Dan Cross) writes: > In article <11al4mu$fqtl$1@kst.eternal-september.org>, > Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote: > >> David Brown <david.brown@hesbynett.no> writes: >> >>> On 13/10/2026 10:38, chine.bleu wrote: >>> >>>> Tim Rentsch wrote: >>>> >>>>> sons[2] array. These links are basically pointers, but held >>>>> as uintptr_t so they can take one of the bits to mean "tall", >>>>> which means taller than the other subtree of the node. The >>>>> tree structure should maintain an invariant that at most one >>>> >>>> Memory is cheap. >>> >>> Not any more! >>> >>>> Do not encode tags into low bits of an address unless you really >>>> know what your doing. >>> >>> Agreed, as a principle. >>> >>>> As a precaution check the return address of malloc >>>> p = malloc(m); >>>> if ((uintptr_t)p)&1!=0) abort(); >>> >>> malloc always returns an address with suitable alignment for any >>> fundamental alignment on the target. > > I don't think this is true anymore, as of C23. Here's the > relevant text from n3220, sec 7.24.3, describing the return > value from `malloc` et al: > > |The pointer returned if the allocation succeeds is suitably > |aligned so that it may be assigned to a pointer to any type of > |object with a fundamental alignment requirement and size less > |than or equal to the size requested. > > This sentence is somewhat ambiguous because it's unclear whether > the "less than or equal to the size requested" criteria applies > to both the pointer type's size _and_ fundamental alignment > requirement, or _just_ the size, [...] It's poorly constructed but in English it has only one grammatical parse.
[toc] | [prev] | [next] | [standalone]
| From | cross@spitfire.i.gajendra.net (Dan Cross) |
|---|---|
| Date | 2026-10-13 21:17 +0000 |
| Message-ID | <11am74c$54g$1@reader2.panix.com> |
| In reply to | #403110 |
In article <86v775h9o2.fsf@linuxsc.com>, Tim Rentsch <tr.17687@z991.linuxsc.com> wrote: >cross@spitfire.i.gajendra.net (Dan Cross) writes: > >> In article <11al4mu$fqtl$1@kst.eternal-september.org>, >> Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote: >> >>> David Brown <david.brown@hesbynett.no> writes: >>> >>>> On 13/10/2026 10:38, chine.bleu wrote: >>>> >>>>> Tim Rentsch wrote: >>>>> >>>>>> sons[2] array. These links are basically pointers, but held >>>>>> as uintptr_t so they can take one of the bits to mean "tall", >>>>>> which means taller than the other subtree of the node. The >>>>>> tree structure should maintain an invariant that at most one >>>>> >>>>> Memory is cheap. >>>> >>>> Not any more! >>>> >>>>> Do not encode tags into low bits of an address unless you really >>>>> know what your doing. >>>> >>>> Agreed, as a principle. >>>> >>>>> As a precaution check the return address of malloc >>>>> p = malloc(m); >>>>> if ((uintptr_t)p)&1!=0) abort(); >>>> >>>> malloc always returns an address with suitable alignment for any >>>> fundamental alignment on the target. >> >> I don't think this is true anymore, as of C23. Here's the >> relevant text from n3220, sec 7.24.3, describing the return >> value from `malloc` et al: >> >> |The pointer returned if the allocation succeeds is suitably >> |aligned so that it may be assigned to a pointer to any type of >> |object with a fundamental alignment requirement and size less >> |than or equal to the size requested. >> >> This sentence is somewhat ambiguous because it's unclear whether >> the "less than or equal to the size requested" criteria applies >> to both the pointer type's size _and_ fundamental alignment >> requirement, or _just_ the size, [...] > >It's poorly constructed but in English it has only one >grammatical parse. Nope. Not even close. - Dan C.
[toc] | [prev] | [next] | [standalone]
| From | "chine.bleu" <chine.bleu@yahoo.com> |
|---|---|
| Date | 2026-10-13 18:01 -0700 |
| Message-ID | <11amk8n$125s6$3@dont-email.me> |
| In reply to | #403124 |
cross@spitfire.i.gajendra.net (Dan Cross) wrote: >>> This sentence is somewhat ambiguous because it's unclear whether >>> >>the "less than or equal to the size requested" criteria applies >>> >>to both the pointer type's size_and_ fundamental alignment >>> >>requirement, or_just_ the size, [...] >> > >> >It's poorly constructed but in English it has only one >> >grammatical parse. Suitable alignment does not guarantee anything about how bits are used in the integer representation. That leads to machine dependent assumptions. Assumptions are deadly if not documented. Testing assumptions is better, -- Siri Seal of Disavowal #777-000. Disavowed. Denied. @ NO KINGS For I desire mercy not sacrifice. /|\ The Church of the Holey Apple .signature 5.5 / \ of Discordian Mysteries. This post insults Islam. Mohamed
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2026-10-13 21:13 -0700 |
| Message-ID | <11amvh2$14pou$3@kst.eternal-september.org> |
| In reply to | #403124 |
cross@spitfire.i.gajendra.net (Dan Cross) writes:
> In article <86v775h9o2.fsf@linuxsc.com>,
> Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
>>cross@spitfire.i.gajendra.net (Dan Cross) writes:
[...]
>>> I don't think this is true anymore, as of C23. Here's the
>>> relevant text from n3220, sec 7.24.3, describing the return
>>> value from `malloc` et al:
>>>
>>> |The pointer returned if the allocation succeeds is suitably
>>> |aligned so that it may be assigned to a pointer to any type of
>>> |object with a fundamental alignment requirement and size less
>>> |than or equal to the size requested.
>>>
>>> This sentence is somewhat ambiguous because it's unclear whether
>>> the "less than or equal to the size requested" criteria applies
>>> to both the pointer type's size _and_ fundamental alignment
>>> requirement, or _just_ the size, [...]
>>
>>It's poorly constructed but in English it has only one
>>grammatical parse.
>
> Nope. Not even close.
I think Tim is right about there being only one grammatical parse.
I'll try to use indentation to indicate (imperfectly) how I parse it:
The pointer returned if the allocation succeeds
is suitably aligned so that
it may be assigned to a pointer to any type of object
with
a fundamental alignment requirement
and·
size less than or equal to the size requested.
So "a fundamental alignment requirement" and "size less than or equal
to the size requested" are parallel requirements, both applying to
the type of the pointed-to object.
I do see a problem with the size requirement being *under* the
"suitably aligned" requirement. It wrongly implies that satisfying
the size requirement contributes to the "suitably aligned" requirement.
But that's not an ambiguous parse.
Do you see a different way to parse the sentence?
--
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 | 2026-10-14 09:43 +0200 |
| Message-ID | <11anbq5$16fmd$1@dont-email.me> |
| In reply to | #403142 |
On 14/10/2026 06:13, Keith Thompson wrote:
> cross@spitfire.i.gajendra.net (Dan Cross) writes:
>> In article <86v775h9o2.fsf@linuxsc.com>,
>> Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
>>> cross@spitfire.i.gajendra.net (Dan Cross) writes:
> [...]
>>>> I don't think this is true anymore, as of C23. Here's the
>>>> relevant text from n3220, sec 7.24.3, describing the return
>>>> value from `malloc` et al:
>>>>
>>>> |The pointer returned if the allocation succeeds is suitably
>>>> |aligned so that it may be assigned to a pointer to any type of
>>>> |object with a fundamental alignment requirement and size less
>>>> |than or equal to the size requested.
>>>>
>>>> This sentence is somewhat ambiguous because it's unclear whether
>>>> the "less than or equal to the size requested" criteria applies
>>>> to both the pointer type's size _and_ fundamental alignment
>>>> requirement, or _just_ the size, [...]
>>>
>>> It's poorly constructed but in English it has only one
>>> grammatical parse.
>>
>> Nope. Not even close.
>
> I think Tim is right about there being only one grammatical parse.
>
> I'll try to use indentation to indicate (imperfectly) how I parse it:
>
> The pointer returned if the allocation succeeds
> is suitably aligned so that
> it may be assigned to a pointer to any type of object
> with
> a fundamental alignment requirement
> and·
> size less than or equal to the size requested.
>
> So "a fundamental alignment requirement" and "size less than or equal
> to the size requested" are parallel requirements, both applying to
> the type of the pointed-to object.
>
> I do see a problem with the size requirement being *under* the
> "suitably aligned" requirement. It wrongly implies that satisfying
> the size requirement contributes to the "suitably aligned" requirement.
> But that's not an ambiguous parse.
>
> Do you see a different way to parse the sentence?
>
I do. "Operators" in English do not have the same clearly defined
grammar rules as operators in C :
The pointer returned if the allocation succeeds
is suitably aligned so that
it may be assigned to a pointer to any type of object
with
a fundamental alignment requirement
and
size
less than or equal to the size requested.
equivalent to :
The pointer returned if the allocation succeeds
is suitably aligned so that
it may be assigned to a pointer to any type of object
with
a fundamental alignment requirement
less than or equal to the size requested.
and
size
less than or equal to the size requested.
If you consider "fundamental alignment requirement" as evaluating to a
number - the result of "alignas" - then I think this parse is also
possible. I would even go as far as to say this was the intended
parsing, because the parsing you gave above would mean the paragraph
only applies to "objects with a fundamental alignment requirement" - and
all complete object types have alignment requirements.
Let us suppose a hypothetical implementation where CHAR_BIT == 8,
sizeof(int) == 4, and alignof(int) == 8.
What guarantees do you have for "void * p = malloc(4);" ?
With your parsing, "p" would be correctly aligned for an int - the
alignment of the type "int" is not relevant to whether the "p" is
correctly aligned or not, only the size of "int" matters.
With the second parsing, "p" may not be correctly aligned for an int -
it is only guaranteed to be aligned for types with alignment
requirements of 4 or less.
That second parsing seems to result in a more logical and consistent
conclusion. But the first parsing seems more reasonable when reading it.
(I do not think any of this will make a difference in practice.)
[toc] | [prev] | [next] | [standalone]
| From | cross@spitfire.i.gajendra.net (Dan Cross) |
|---|---|
| Date | 2026-10-14 20:11 +0000 |
| Message-ID | <11aonlg$bhk$1@reader2.panix.com> |
| In reply to | #403145 |
In article <11anbq5$16fmd$1@dont-email.me>, David Brown <david.brown@hesbynett.no> wrote: >On 14/10/2026 06:13, Keith Thompson wrote: >> [snip] >> So "a fundamental alignment requirement" and "size less than or equal >> to the size requested" are parallel requirements, both applying to >> the type of the pointed-to object. >> >> I do see a problem with the size requirement being *under* the >> "suitably aligned" requirement. It wrongly implies that satisfying >> the size requirement contributes to the "suitably aligned" requirement. >> But that's not an ambiguous parse. >> >> Do you see a different way to parse the sentence? > >I do. "Operators" in English do not have the same clearly defined >grammar rules as operators in C : > > The pointer returned if the allocation succeeds > is suitably aligned so that > it may be assigned to a pointer to any type of object > with > a fundamental alignment requirement > and > size > less than or equal to the size requested. > >equivalent to : > > The pointer returned if the allocation succeeds > is suitably aligned so that > it may be assigned to a pointer to any type of object > with > a fundamental alignment requirement > less than or equal to the size requested. > and > size > less than or equal to the size requested. Indeed. And in fact, I found some direct evidence for exactly this interpretation (the one I claimed was correct). Draft 3054 (https://open-std.org/JTC1/SC22/WG14/www/docs/n3054.pdf) includes this in the abstract: |The following documents, for all intents and purposes, have |been applied to this draft from before and during the October |2019 Meeting: | ... (on down to the 6th from the top on the second page): | - N2293 Alignment requirements for memory management functions In turn, N2293 goes into detail about the change, the motivation and the present wording in C23; specifically, it is clear that they mean for the requested allocation size to factor in the fundamental alignment requirement of the pointed-to type. The Summary section reads: |The alignment requirements of `malloc`, `calloc`, and `realloc` |are somewhat confusingly phrased, in a way that affects small |allocations (sizes less than `_Alignof(max_align_t))`. Some |readers (and implementations) interpret them to demand |`_Alignof(max_align_t)`-alignment even for allocation sizes |that could not hold an object with that alignment. We call |this the "strong-alignment" reading. Other readers (and |implementations) interpret them as requiring the returned |memory to be aligned only enough to accommodate those types |that could inhabit the returned memory. In particular, since |`sizeof(T) >= _Alignof(T)` for all portably defined types `T`, |allocations with sizes smaller than `_Alignof(max_align_t)` |need only be aligned to the largest power of two less than or |equal to the requested size. We call this the "weak-alignment" |reading. | |Many implementations only provide weak-alignment guarantees, |and some cases these guarantees are important in conserving |both CPU and memory. Therefore, we propose clarifying the |wording such that the weak-alignment implementation is |unambiguously allowed. Strong-alignment implementations remain |correct, and may document the guarantee as an extension. (https://www.open-std.org/JTC1/SC22/WG14/www/docs/n2293.htm) I don't think we can get much more definitive than that. - Dan C.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2026-10-14 15:25 -0700 |
| Message-ID | <11aovg9$1t8gq$1@kst.eternal-september.org> |
| In reply to | #403145 |
David Brown <david.brown@hesbynett.no> writes:
> On 14/10/2026 06:13, Keith Thompson wrote:
>> cross@spitfire.i.gajendra.net (Dan Cross) writes:
>>> In article <86v775h9o2.fsf@linuxsc.com>,
>>> Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
>>>> cross@spitfire.i.gajendra.net (Dan Cross) writes:
>> [...]
>>>>> I don't think this is true anymore, as of C23. Here's the
>>>>> relevant text from n3220, sec 7.24.3, describing the return
>>>>> value from `malloc` et al:
>>>>>
>>>>> |The pointer returned if the allocation succeeds is suitably
>>>>> |aligned so that it may be assigned to a pointer to any type of
>>>>> |object with a fundamental alignment requirement and size less
>>>>> |than or equal to the size requested.
>>>>>
>>>>> This sentence is somewhat ambiguous because it's unclear whether
>>>>> the "less than or equal to the size requested" criteria applies
>>>>> to both the pointer type's size _and_ fundamental alignment
>>>>> requirement, or _just_ the size, [...]
>>>>
>>>> It's poorly constructed but in English it has only one
>>>> grammatical parse.
>>>
>>> Nope. Not even close.
>>
>> I think Tim is right about there being only one grammatical parse.
>> I'll try to use indentation to indicate (imperfectly) how I parse
>> it:
>>
>> The pointer returned if the allocation succeeds
>> is suitably aligned so that
>> it may be assigned to a pointer to any type of object
>> with
>> a fundamental alignment requirement
>> and·
>> size less than or equal to the size requested.
>>
>> So "a fundamental alignment requirement" and "size less than or equal
>> to the size requested" are parallel requirements, both applying to
>> the type of the pointed-to object.
>>
>> I do see a problem with the size requirement being *under* the
>> "suitably aligned" requirement. It wrongly implies that satisfying
>> the size requirement contributes to the "suitably aligned" requirement.
>> But that's not an ambiguous parse.
>>
>> Do you see a different way to parse the sentence?
>
> I do. "Operators" in English do not have the same clearly defined
> grammar rules as operators in C :
>
> The pointer returned if the allocation succeeds
> is suitably aligned so that
> it may be assigned to a pointer to any type of object
> with
> a fundamental alignment requirement
> and
> size
> less than or equal to the size requested.
>
> equivalent to :
>
> The pointer returned if the allocation succeeds
> is suitably aligned so that
> it may be assigned to a pointer to any type of object
> with
> a fundamental alignment requirement
> less than or equal to the size requested.
> and
> size
> less than or equal to the size requested.
>
> If you consider "fundamental alignment requirement" as evaluating to a
> number - the result of "alignas" - then I think this parse is also
> possible. I would even go as far as to say this was the intended
> parsing, because the parsing you gave above would mean the paragraph
> only applies to "objects with a fundamental alignment requirement" -
> and all complete object types have alignment requirements.
I think you're missing the fact that "fundamental alignment" is a
defined term. N3220 6.2.8p2:
A *fundamental alignment* is a valid alignment less than or equal to
alignof(max_align_t).
And p3:
An *extended alignment* is represented by an alignment greater
than alignof(max_align_t). It is implementation-defined whether
any extended alignments are supported and the storage durations
for which they are supported. A type having an extended alignment
requirement is an *over-aligned* type.
The point is that malloc() cannot reliably allocate objects of
over-aligned types. C23 adds aligned_alloc() for that.
I read "a fundamental alignment requirement" as a predicate; a
give object type always has an alignment, and may or may not have
a fundamental alignment requirement.
I think I now agree about the ambiguous parse, but I don't think it
matters, because an object type's alignment cannot be greater than its
size. I'm not sure that's stated explicitly, but otherwise arrays
wouldn't work (or the language would have to allow alignment gaps
between array elements).
> Let us suppose a hypothetical implementation where CHAR_BIT == 8,
> sizeof(int) == 4, and alignof(int) == 8.
That's not possible. Arrays of int cannot have gaps between the
elements.
[...]
--
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 | 2026-10-15 09:28 +0200 |
| Message-ID | <11apvau$25qhp$1@dont-email.me> |
| In reply to | #403171 |
On 15/10/2026 00:25, Keith Thompson wrote: > David Brown <david.brown@hesbynett.no> writes: >> On 14/10/2026 06:13, Keith Thompson wrote: >>> cross@spitfire.i.gajendra.net (Dan Cross) writes: >>>> In article <86v775h9o2.fsf@linuxsc.com>, >>>> Tim Rentsch <tr.17687@z991.linuxsc.com> wrote: >>>>> cross@spitfire.i.gajendra.net (Dan Cross) writes: >>> [...] >>>>>> I don't think this is true anymore, as of C23. Here's the >>>>>> relevant text from n3220, sec 7.24.3, describing the return >>>>>> value from `malloc` et al: >>>>>> >>>>>> |The pointer returned if the allocation succeeds is suitably >>>>>> |aligned so that it may be assigned to a pointer to any type of >>>>>> |object with a fundamental alignment requirement and size less >>>>>> |than or equal to the size requested. >>>>>> >>>>>> This sentence is somewhat ambiguous because it's unclear whether >>>>>> the "less than or equal to the size requested" criteria applies >>>>>> to both the pointer type's size _and_ fundamental alignment >>>>>> requirement, or _just_ the size, [...] >>>>> >>>>> It's poorly constructed but in English it has only one >>>>> grammatical parse. >>>> >>>> Nope. Not even close. >>> >>> I think Tim is right about there being only one grammatical parse. >>> I'll try to use indentation to indicate (imperfectly) how I parse >>> it: >>> >>> The pointer returned if the allocation succeeds >>> is suitably aligned so that >>> it may be assigned to a pointer to any type of object >>> with >>> a fundamental alignment requirement >>> and· >>> size less than or equal to the size requested. >>> >>> So "a fundamental alignment requirement" and "size less than or equal >>> to the size requested" are parallel requirements, both applying to >>> the type of the pointed-to object. >>> >>> I do see a problem with the size requirement being *under* the >>> "suitably aligned" requirement. It wrongly implies that satisfying >>> the size requirement contributes to the "suitably aligned" requirement. >>> But that's not an ambiguous parse. >>> >>> Do you see a different way to parse the sentence? >> >> I do. "Operators" in English do not have the same clearly defined >> grammar rules as operators in C : >> >> The pointer returned if the allocation succeeds >> is suitably aligned so that >> it may be assigned to a pointer to any type of object >> with >> a fundamental alignment requirement >> and >> size >> less than or equal to the size requested. >> >> equivalent to : >> >> The pointer returned if the allocation succeeds >> is suitably aligned so that >> it may be assigned to a pointer to any type of object >> with >> a fundamental alignment requirement >> less than or equal to the size requested. >> and >> size >> less than or equal to the size requested. >> >> If you consider "fundamental alignment requirement" as evaluating to a >> number - the result of "alignas" - then I think this parse is also >> possible. I would even go as far as to say this was the intended >> parsing, because the parsing you gave above would mean the paragraph >> only applies to "objects with a fundamental alignment requirement" - >> and all complete object types have alignment requirements. > > I think you're missing the fact that "fundamental alignment" is a > defined term. N3220 6.2.8p2: > > A *fundamental alignment* is a valid alignment less than or equal to > alignof(max_align_t). > I am aware of that definition, and did not miss it. > And p3: > > An *extended alignment* is represented by an alignment greater > than alignof(max_align_t). It is implementation-defined whether > any extended alignments are supported and the storage durations > for which they are supported. A type having an extended alignment > requirement is an *over-aligned* type. Again, I read that too. > > The point is that malloc() cannot reliably allocate objects of > over-aligned types. C23 adds aligned_alloc() for that. Yes. > > I read "a fundamental alignment requirement" as a predicate; a > give object type always has an alignment, and may or may not have > a fundamental alignment requirement. Yes, I can see that is how you read it. And I also think that is the more obvious reading of the paragraph. I just don't think it is the only one. > > I think I now agree about the ambiguous parse, but I don't think it > matters, because an object type's alignment cannot be greater than its > size. I'm not sure that's stated explicitly, but otherwise arrays > wouldn't work (or the language would have to allow alignment gaps > between array elements). > >> Let us suppose a hypothetical implementation where CHAR_BIT == 8, >> sizeof(int) == 4, and alignof(int) == 8. > > That's not possible. Arrays of int cannot have gaps between the > elements. > That does sound right. An implementation that wanted to keep its 32-bit ints in 64-bit slots would have to have the size of the int as the full 64-bit, with 32 of those bits being padding. So my hypothetical implementation here could not exist. (Dan's recent post - as is often the case - is more complete and considered, and better researched than mine, so I defer to that for why the changes were made to the standard and how they should be interpreted.)
[toc] | [prev] | [next] | [standalone]
| From | cross@spitfire.i.gajendra.net (Dan Cross) |
|---|---|
| Date | 2026-10-14 14:13 +0000 |
| Message-ID | <11ao2mr$4l9$1@reader2.panix.com> |
| In reply to | #403142 |
In article <11amvh2$14pou$3@kst.eternal-september.org>,
Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
>cross@spitfire.i.gajendra.net (Dan Cross) writes:
>> In article <86v775h9o2.fsf@linuxsc.com>,
>> Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
>>>cross@spitfire.i.gajendra.net (Dan Cross) writes:
>[...]
>>>> I don't think this is true anymore, as of C23. Here's the
>>>> relevant text from n3220, sec 7.24.3, describing the return
>>>> value from `malloc` et al:
>>>>
>>>> |The pointer returned if the allocation succeeds is suitably
>>>> |aligned so that it may be assigned to a pointer to any type of
>>>> |object with a fundamental alignment requirement and size less
>>>> |than or equal to the size requested.
>>>>
>>>> This sentence is somewhat ambiguous because it's unclear whether
>>>> the "less than or equal to the size requested" criteria applies
>>>> to both the pointer type's size _and_ fundamental alignment
>>>> requirement, or _just_ the size, [...]
>>>
>>>It's poorly constructed but in English it has only one
>>>grammatical parse.
>>
>> Nope. Not even close.
>
>I think Tim is right about there being only one grammatical parse.
No, he is not. There are over a thousand ways to parse that
sentence "grammatically", according to the "standard" rules of
the English language (a language infamous for having little in
the way of standard rules).
We tend to discount those since we're close to the domain, but
ask a linguist what they think about this sentence and they will
point out ambiguities. Or use a tool like spaCy to visualize
the parse trees (from which one can see that those ambiguities
lead to a combinatorial explosion of valid parses).
Fortunately, most of these have overlapping meanings, and there
are only two potentially meaningful interpretations, one where
the size requirement of the request attaches only to the size of
the pointed-to type, or one where it attaches to both the size
and fundamental alignment requirement of the pointed-to type.
>I'll try to use indentation to indicate (imperfectly) how I parse it:
>
>The pointer returned if the allocation succeeds
> is suitably aligned so that
> it may be assigned to a pointer to any type of object
> with
> a fundamental alignment requirement
> and·
> size less than or equal to the size requested.
>
>So "a fundamental alignment requirement" and "size less than or equal
>to the size requested" are parallel requirements, both applying to
>the type of the pointed-to object.
That is one of the two reasonable interpretations. The other is
that the requirements placed on size and fundamental alignment
of the pointer type are cumulative and dependent on the size of
the allocation. If so, then nothing in the C standard prevents
an implementation from from returning a pointer aligned to
`alignof(char)` for `malloc(1)`.
>I do see a problem with the size requirement being *under* the
>"suitably aligned" requirement. It wrongly implies that satisfying
>the size requirement contributes to the "suitably aligned" requirement.
>But that's not an ambiguous parse.
>
>Do you see a different way to parse the sentence?
Adopting your notation, the other meaningful way is
If the allocation succeeds:
The pointer returned is suitably aligned so that:
It may be asigned to a pointer to any type of object with:
a fundamental alignment requirement _and_ size,
less than or equal to the size requested.
This is a grammatically valid parse of that sentence. Given the
existence of `aligned_alloc`, I can't think of a great reason
why this second interpretation should be prohibited; there are
esoteric hardware structures that do things like align 32-bit
registers on 128-bit boundaries (e.g., the MMIO registers for
the x86 xAPIC), but pointers to those are not the domain of
`malloc`.
Btw, this kind of ambiguity is the primary objection I have to
attempts at using informal English prose to precisely define a
programming language.
- Dan C.
[toc] | [prev] | [next] | [standalone]
| From | Janis Papanagnou <janis_papanagnou+ng@hotmail.com> |
|---|---|
| Date | 2026-10-14 18:03 +0200 |
| Message-ID | <11ao94e$4o6l$6@dont-email.me> |
| In reply to | #403152 |
On 2026-10-14 16:13, Dan Cross wrote: > > Btw, this kind of ambiguity is the primary objection I have to > attempts at using informal English prose to precisely define a > programming language. I'm curious; are there any more "recent" languages (i.e. younger than 50 years old) that don't use English (or any other informal language) (as opposed to a ["fully"] formal specification)? Beyond Algol 68 I found a respective statement only about ML/SML; is that all? Janis
[toc] | [prev] | [next] | [standalone]
| From | cross@spitfire.i.gajendra.net (Dan Cross) |
|---|---|
| Date | 2026-10-14 18:21 +0000 |
| Message-ID | <11aoh85$b12$1@reader2.panix.com> |
| In reply to | #403157 |
In article <11ao94e$4o6l$6@dont-email.me>, Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote: >On 2026-10-14 16:13, Dan Cross wrote: >> >> Btw, this kind of ambiguity is the primary objection I have to >> attempts at using informal English prose to precisely define a >> programming language. > >I'm curious; are there any more "recent" languages (i.e. younger >than 50 years old) that don't use English (or any other informal >language) (as opposed to a ["fully"] formal specification)? > >Beyond Algol 68 I found a respective statement only about ML/SML; >is that all? Beyond SML? I'm afraid I don't know. - Dan C.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2026-10-14 15:42 -0700 |
| Message-ID | <11ap0fo$1t8gq$2@kst.eternal-september.org> |
| In reply to | #403152 |
cross@spitfire.i.gajendra.net (Dan Cross) writes:
> In article <11amvh2$14pou$3@kst.eternal-september.org>,
> Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
>>cross@spitfire.i.gajendra.net (Dan Cross) writes:
>>> In article <86v775h9o2.fsf@linuxsc.com>,
>>> Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
>>>>cross@spitfire.i.gajendra.net (Dan Cross) writes:
>>[...]
>>>>> I don't think this is true anymore, as of C23. Here's the
>>>>> relevant text from n3220, sec 7.24.3, describing the return
>>>>> value from `malloc` et al:
>>>>>
>>>>> |The pointer returned if the allocation succeeds is suitably
>>>>> |aligned so that it may be assigned to a pointer to any type of
>>>>> |object with a fundamental alignment requirement and size less
>>>>> |than or equal to the size requested.
>>>>>
>>>>> This sentence is somewhat ambiguous because it's unclear whether
>>>>> the "less than or equal to the size requested" criteria applies
>>>>> to both the pointer type's size _and_ fundamental alignment
>>>>> requirement, or _just_ the size, [...]
>>>>
>>>>It's poorly constructed but in English it has only one
>>>>grammatical parse.
>>>
>>> Nope. Not even close.
>>
>>I think Tim is right about there being only one grammatical parse.
>
> No, he is not. There are over a thousand ways to parse that
> sentence "grammatically", according to the "standard" rules of
> the English language (a language infamous for having little in
> the way of standard rules).
>
> We tend to discount those since we're close to the domain, but
> ask a linguist what they think about this sentence and they will
> point out ambiguities. Or use a tool like spaCy to visualize
> the parse trees (from which one can see that those ambiguities
> lead to a combinatorial explosion of valid parses).
>
> Fortunately, most of these have overlapping meanings, and there
> are only two potentially meaningful interpretations, one where
> the size requirement of the request attaches only to the size of
> the pointed-to type, or one where it attaches to both the size
> and fundamental alignment requirement of the pointed-to type.
>
>>I'll try to use indentation to indicate (imperfectly) how I parse it:
>>
>>The pointer returned if the allocation succeeds
>> is suitably aligned so that
>> it may be assigned to a pointer to any type of object
>> with
>> a fundamental alignment requirement
>> and
>> size less than or equal to the size requested.
>>
>>So "a fundamental alignment requirement" and "size less than or equal
>>to the size requested" are parallel requirements, both applying to
>>the type of the pointed-to object.
>
> That is one of the two reasonable interpretations. The other is
> that the requirements placed on size and fundamental alignment
> of the pointer type are cumulative and dependent on the size of
> the allocation. If so, then nothing in the C standard prevents
> an implementation from from returning a pointer aligned to
> `alignof(char)` for `malloc(1)`.
I do see the parsing ambiguity now.
I believe that's consistent with the way I parsed it. A successful
malloc(1) returns a value that can be assigned to a pointer of type
char*, which points to the object type "char", which does have (a
fundamental alignment requirement) and (a size less than or equal
to the size requested).
>>I do see a problem with the size requirement being *under* the
>>"suitably aligned" requirement. It wrongly implies that satisfying
>>the size requirement contributes to the "suitably aligned" requirement.
>>But that's not an ambiguous parse.
>>
>>Do you see a different way to parse the sentence?
>
> Adopting your notation, the other meaningful way is
>
> If the allocation succeeds:
> The pointer returned is suitably aligned so that:
> It may be asigned to a pointer to any type of object with:
> a fundamental alignment requirement _and_ size,
> less than or equal to the size requested.
>
> This is a grammatically valid parse of that sentence. Given the
> existence of `aligned_alloc`, I can't think of a great reason
> why this second interpretation should be prohibited; there are
> esoteric hardware structures that do things like align 32-bit
> registers on 128-bit boundaries (e.g., the MMIO registers for
> the x86 xAPIC), but pointers to those are not the domain of
> `malloc`.
If you allow an object type to have an alignment greater than its
size, then the ambiguity can result in an actual difference in the
requirements. But then arrays don't work.
> Btw, this kind of ambiguity is the primary objection I have to
> attempts at using informal English prose to precisely define a
> programming language.
I'm not sure that anything other than English (or other human
language) prose would be a practical way to define C. There have
been attempts to define formal semantics for C, but they haven't
caught on.
--
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 | cross@spitfire.i.gajendra.net (Dan Cross) |
|---|---|
| Date | 2026-10-15 14:25 +0000 |
| Message-ID | <11aqnp0$sb$1@reader2.panix.com> |
| In reply to | #403172 |
In article <11ap0fo$1t8gq$2@kst.eternal-september.org>, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote: >cross@spitfire.i.gajendra.net (Dan Cross) writes: >> In article <11amvh2$14pou$3@kst.eternal-september.org>, >> Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote: >>>[snip] >>>So "a fundamental alignment requirement" and "size less than or equal >>>to the size requested" are parallel requirements, both applying to >>>the type of the pointed-to object. >> >> That is one of the two reasonable interpretations. The other is >> that the requirements placed on size and fundamental alignment >> of the pointer type are cumulative and dependent on the size of >> the allocation. If so, then nothing in the C standard prevents >> an implementation from from returning a pointer aligned to >> `alignof(char)` for `malloc(1)`. > >I do see the parsing ambiguity now. > >I believe that's consistent with the way I parsed it. A successful >malloc(1) returns a value that can be assigned to a pointer of type >char*, which points to the object type "char", which does have (a >fundamental alignment requirement) and (a size less than or equal >to the size requested). Right, but I think it's a bit deeper than that. Somewhat informally, the C17 wording could be read as requiring that the pointer returned from `malloc` must be suitable for assignment to any pointer to a type with `alignof(max_align_t)` regardless of the requested size, which might be smaller. N2293 calls this the, '"strong-alignment" reading.' Under that reading, even if the requested size can't hold an object of a type with a stricter fundamental alignment requirement because it's too small, the return value from malloc is artificially constrained so that the pointer refers to an address that is aligned to `alignof(max_align_t)`. For example, an x86_64 implementation following the System V ABI would always return a pointer to an address aligned on a 16-byte boundary, even for `malloc(1)`. The N2293 wording adopted in C23 says that that need not be the case. An implementation can choose to return a pointer that is more strictly aligned for a small allocation (internally, lots of `malloc`s have some minimum allocation size that is greater than `sizeof(max_align_t)` and return all pointers aligned to whatever that is), but it does not have to (e.g., in some applications space is at a premium, so small allocations might be handled specially). >[snip] >If you allow an object type to have an alignment greater than its >size, then the ambiguity can result in an actual difference in the >requirements. But then arrays don't work. That's ok; this is only about the properties vis alignment of the pointer returned from malloc. Consider x86_64 with the System V ABI again or ARM64 with the AAPCS; suppose that `char *p = malloc(char[3]);` assigns a non-NULL ponter to `p`. The question is only whether or not the address `p` refers to is required to be aligned on a 16-byte boundary; under the '"strong-alignment" reading' in N2293, it is, even though the allocated size is only 3. Under the '"weak-alignment" reading', the return address can aligned on an even boundary, and C23 codified the weak-alignment reading. Note that neither reading says anything about the size of elements or their alignment in an allocation that is treated like an array; it only affects the alignment of the starting address. N2293 mentions this, but it probably bears repeating here: the utility of forcing `malloc` to align small allocations to e.g., `alignof(max_align_t)` seems mostly restricted to having some hope of overloading the low bits of the returned address for some program-specific purpose, which is how this came up in the first place in this thread. As has already been mentioned, the standard makes no guarnatee about the integer representation of addresses, so this is already somewhat fraught, but on many platforms we may assume that as a practical matter, for a pointer to a suitably aligned address, those bits will be clear as a practical matter; I suppose if one wants that for a small allocation, use `aligned_alloc`. Caveat emptor. >> Btw, this kind of ambiguity is the primary objection I have to >> attempts at using informal English prose to precisely define a >> programming language. > >I'm not sure that anything other than English (or other human >language) prose would be a practical way to define C. There have >been attempts to define formal semantics for C, but they haven't >caught on. Yeah. For C, I think that it would be nearly impossible to retrofit onto the language at this point. I have high hopes for Rust, but folks I've spoken to who have been active in the Rust formal methods interesting group seem pessimistic about a formally defined semantics, which is a shame. - Dan C.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2026-10-15 15:54 -0700 |
| Message-ID | <11arlj9$2q39c$1@kst.eternal-september.org> |
| In reply to | #403188 |
cross@spitfire.i.gajendra.net (Dan Cross) writes:
> In article <11ap0fo$1t8gq$2@kst.eternal-september.org>,
> Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
>>cross@spitfire.i.gajendra.net (Dan Cross) writes:
>>> In article <11amvh2$14pou$3@kst.eternal-september.org>,
>>> Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
>>>>[snip]
>>>>So "a fundamental alignment requirement" and "size less than or equal
>>>>to the size requested" are parallel requirements, both applying to
>>>>the type of the pointed-to object.
>>>
>>> That is one of the two reasonable interpretations. The other is
>>> that the requirements placed on size and fundamental alignment
>>> of the pointer type are cumulative and dependent on the size of
>>> the allocation. If so, then nothing in the C standard prevents
>>> an implementation from from returning a pointer aligned to
>>> `alignof(char)` for `malloc(1)`.
>>
>>I do see the parsing ambiguity now.
>>
>>I believe that's consistent with the way I parsed it. A successful
>>malloc(1) returns a value that can be assigned to a pointer of type
>>char*, which points to the object type "char", which does have (a
>>fundamental alignment requirement) and (a size less than or equal
>>to the size requested).
>
> Right, but I think it's a bit deeper than that.
>
> Somewhat informally, the C17 wording could be read as requiring
> that the pointer returned from `malloc` must be suitable for
> assignment to any pointer to a type with `alignof(max_align_t)`
> regardless of the requested size, which might be smaller. N2293
> calls this the, '"strong-alignment" reading.'
The C17 wording is:
The pointer returned if the allocation succeeds is suitably aligned
so that it may be assigned to a pointer to any type of object with a
fundamental alignment requirement and then used to access such an
object or an array of such objects in the space allocated (until the
space is explicitly deallocated).
I don't see any other way to interpret that. It requires that
a pointer returned by a successful malloc() must *always* be
suitably aligned. A pointer returned by malloc(1) must be aligned
so that it can point to a long long, for example.
It overlooks the fact that it can't point to a long long, because
there isn't room for it. And there's no portable way to tell if an
implementation violates this requirement. If an implementation's
malloc(1) returns an "odd" pointer, it violates the standard's
requirement, but that violation likely has no real effect.
For C23, it was recognized that requiring strict alignment for
tiny allocations is neither useful nor necessarily meaningful.
malloc(1) might as well be allowed to return an "odd" pointer.
> Under that reading, even if the requested size can't hold an
> object of a type with a stricter fundamental alignment
> requirement because it's too small, the return value from malloc
> is artificially constrained so that the pointer refers to an
> address that is aligned to `alignof(max_align_t)`. For example,
> an x86_64 implementation following the System V ABI would always
> return a pointer to an address aligned on a 16-byte boundary,
> even for `malloc(1)`.
And of course that conforms to both the C17 and the C2y requirements.
> The N2293 wording adopted in C23 says that that need not be the
> case. An implementation can choose to return a pointer that is
> more strictly aligned for a small allocation (internally, lots
> of `malloc`s have some minimum allocation size that is greater
> than `sizeof(max_align_t)` and return all pointers aligned to
> whatever that is), but it does not have to (e.g., in some
> applications space is at a premium, so small allocations might
> be handled specially).
Right.
>>[snip]
>>If you allow an object type to have an alignment greater than its
>>size, then the ambiguity can result in an actual difference in the
>>requirements. But then arrays don't work.
>
> That's ok; this is only about the properties vis alignment of
> the pointer returned from malloc. Consider x86_64 with the
> System V ABI again or ARM64 with the AAPCS; suppose that
> `char *p = malloc(char[3]);` assigns a non-NULL ponter to `p`.
Alas, that's a syntax error. The argument to malloc is an expression,
not a type. (I'm certain you knew that.) You can write
`malloc(sizeof (char[3])`, but that's just malloc(3); no type
information is passed.
And the alignment of char[3] is 1. An array of two char[3] objects has
a size of 6; there are no alignment gaps between the elements.
> The question is only whether or not the address `p` refers to is
> required to be aligned on a 16-byte boundary; under the
> '"strong-alignment" reading' in N2293, it is, even though the
> allocated size is only 3. Under the '"weak-alignment" reading',
> the return address can aligned on an even boundary, and C23
> codified the weak-alignment reading. Note that neither reading
> says anything about the size of elements or their alignment in
> an allocation that is treated like an array; it only affects
> the alignment of the starting address.
Under C17, the result of malloc(3) must be strongly aligned (8
bytes, for example). Under C23, it has to be at least 2 if there
are any types with 2-byte alignment.
> N2293 mentions this, but it probably bears repeating here: the
> utility of forcing `malloc` to align small allocations to e.g.,
> `alignof(max_align_t)` seems mostly restricted to having some
> hope of overloading the low bits of the returned address for
> some program-specific purpose, which is how this came up in the
> first place in this thread.
It hadn't occurred to me that that might be the reason. I assumed
it was just because strong alignment for small allocations is not
useful and should not be required. Allocating single bytes for
malloc(1) calls could have real advantages for some programs, and
the standard shouldn't prohibit that.
As I recall, there was a discussion about reusing low-order bits of
pointers, and the fact that malloc(1) no longer has to be strongly
aligned became relevant to that. It doesn't imply that that was
the reason.
There might be an ambiguity in the English grammar of the C23
statement about the alignment of malloc()ed pointers, but I don't
*think* we've seen a case where the two (or more?) different
interpretations actually lead to different semantics.
> As has already been mentioned, the
> standard makes no guarnatee about the integer representation of
> addresses, so this is already somewhat fraught, but on many
> platforms we may assume that as a practical matter, for a
> pointer to a suitably aligned address, those bits will be clear
> as a practical matter; I suppose if one wants that for a small
> allocation, use `aligned_alloc`. Caveat emptor.
Yes, if you need aligned pointers, aligned_alloc() is the way to
get them. aligned_alloc(8, 1) gives you an 8-byte aligned pointer
to a 1-byte object; if that's useful, it's because you're doing
something weird. And if you need to fiddle with the low-order
bits of aligned pointers, you could run into the problems we've
already discussed.
[snip]
--
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 | Kaz Kylheku <046-301-5902@kylheku.com> |
|---|---|
| Date | 2026-10-15 23:51 +0000 |
| Message-ID | <20261015163445.76@kylheku.com> |
| In reply to | #403200 |
On 2026-10-15, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote: > cross@spitfire.i.gajendra.net (Dan Cross) writes: >> In article <11ap0fo$1t8gq$2@kst.eternal-september.org>, >> Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote: >>>cross@spitfire.i.gajendra.net (Dan Cross) writes: >>>> In article <11amvh2$14pou$3@kst.eternal-september.org>, >>>> Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote: >>>>>[snip] >>>>>So "a fundamental alignment requirement" and "size less than or equal >>>>>to the size requested" are parallel requirements, both applying to >>>>>the type of the pointed-to object. >>>> >>>> That is one of the two reasonable interpretations. The other is >>>> that the requirements placed on size and fundamental alignment >>>> of the pointer type are cumulative and dependent on the size of >>>> the allocation. If so, then nothing in the C standard prevents >>>> an implementation from from returning a pointer aligned to >>>> `alignof(char)` for `malloc(1)`. >>> >>>I do see the parsing ambiguity now. >>> >>>I believe that's consistent with the way I parsed it. A successful >>>malloc(1) returns a value that can be assigned to a pointer of type >>>char*, which points to the object type "char", which does have (a >>>fundamental alignment requirement) and (a size less than or equal >>>to the size requested). >> >> Right, but I think it's a bit deeper than that. >> >> Somewhat informally, the C17 wording could be read as requiring >> that the pointer returned from `malloc` must be suitable for >> assignment to any pointer to a type with `alignof(max_align_t)` >> regardless of the requested size, which might be smaller. N2293 >> calls this the, '"strong-alignment" reading.' > > The C17 wording is: > > The pointer returned if the allocation succeeds is suitably aligned > so that it may be assigned to a pointer to any type of object with a > fundamental alignment requirement and then used to access such an > object or an array of such objects in the space allocated (until the > space is explicitly deallocated). I suspect that this should be read as "any type of object which can fit into the requested size". > I don't see any other way to interpret that. It can be interpreted a a defect. Note that in a single sentence, the requirement is being given that: - the pointer from a successful allocation is aligned for any object - the pointer can be used to access such an object ... in the space allocated From that we can infer that "any type" cannot literally be any type Because if we have a successful malloc(1) and we choose "long long" to be any type, the literally interpreted requirements are that we can convert the pointer to "long long *" and use the resulting pointer for access. That requires a malloc(1) to be adjusted to malloc(sizeof (long long)); the requirement goes beyond alignment. It must be that "any type" means "any type that can be stored in the space allocated". Then the whole thing makes sense; yes, the pointer can be converted to that type and used to access such an object in the space allocated, because it fits. -- TXR Programming Language: http://nongnu.org/txr Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal Mastodon: @Kazinator@mstdn.ca
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2026-10-15 18:14 -0700 |
| Message-ID | <11artp4$2tcf0$1@kst.eternal-september.org> |
| In reply to | #403201 |
Kaz Kylheku <046-301-5902@kylheku.com> writes:
> On 2026-10-15, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
>> cross@spitfire.i.gajendra.net (Dan Cross) writes:
>>> In article <11ap0fo$1t8gq$2@kst.eternal-september.org>,
>>> Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
>>>>cross@spitfire.i.gajendra.net (Dan Cross) writes:
>>>>> In article <11amvh2$14pou$3@kst.eternal-september.org>,
>>>>> Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
>>>>>>[snip]
>>>>>>So "a fundamental alignment requirement" and "size less than or equal
>>>>>>to the size requested" are parallel requirements, both applying to
>>>>>>the type of the pointed-to object.
>>>>>
>>>>> That is one of the two reasonable interpretations. The other is
>>>>> that the requirements placed on size and fundamental alignment
>>>>> of the pointer type are cumulative and dependent on the size of
>>>>> the allocation. If so, then nothing in the C standard prevents
>>>>> an implementation from from returning a pointer aligned to
>>>>> `alignof(char)` for `malloc(1)`.
>>>>
>>>>I do see the parsing ambiguity now.
>>>>
>>>>I believe that's consistent with the way I parsed it. A successful
>>>>malloc(1) returns a value that can be assigned to a pointer of type
>>>>char*, which points to the object type "char", which does have (a
>>>>fundamental alignment requirement) and (a size less than or equal
>>>>to the size requested).
>>>
>>> Right, but I think it's a bit deeper than that.
>>>
>>> Somewhat informally, the C17 wording could be read as requiring
>>> that the pointer returned from `malloc` must be suitable for
>>> assignment to any pointer to a type with `alignof(max_align_t)`
>>> regardless of the requested size, which might be smaller. N2293
>>> calls this the, '"strong-alignment" reading.'
>>
>> The C17 wording is:
>>
>> The pointer returned if the allocation succeeds is suitably aligned
>> so that it may be assigned to a pointer to any type of object with a
>> fundamental alignment requirement and then used to access such an
>> object or an array of such objects in the space allocated (until the
>> space is explicitly deallocated).
>
> I suspect that this should be read as "any type of object which can
> fit into the requested size".
>
>> I don't see any other way to interpret that.
>
> It can be interpreted a a defect.
Sure. My point is that I see no ambiguity in the C17 wording. A
non-null pointer returned by malloc() must be "suitably aligned".
Yes, it's a defect. What it says is clear. What it says is also
logically inconsistent.
Given a typical memory model (not mandated by the standard), it could
mean that a successful malloc(1) must return a pointer whose low-order N
bits are zero, where N is typically about 3 or 4. Of course the
standard couldn't express it that way.
> Note that in a single sentence, the requirement is being given that:
>
> - the pointer from a successful allocation is aligned for any object
>
> - the pointer can be used to access such an object ... in the space
> allocated
>
> From that we can infer that "any type" cannot literally be any type
> Because if we have a successful malloc(1) and we choose "long long" to
> be any type, the literally interpreted requirements are that we can
> convert the pointer to "long long *" and use the resulting pointer for
> access. That requires a malloc(1) to be adjusted to malloc(sizeof (long
> long)); the requirement goes beyond alignment.
>
> It must be that "any type" means "any type that can be
> stored in the space allocated".
But that's not what it says.
> Then the whole thing makes sense; yes, the pointer can be converted
> to that type and used to access such an object in the space allocated,
> because it fits.
Yes, the whole thing makes sense if you change the wording. That's
what C23 did (perhaps not entirely successfully); it corrected
the defect.
There is at least one possibly visible semantic change from the
C23 wording. Assume alignof(long double) > 16. In C17, this
is well defined (if malloc succeeds, and given the most nearly
reasonable interpretation of the defective C17 wording):
long double *p = malloc(1);
though any attempt to dereference p has undefined behavior. In C23,
it can have undefined behavior if the pointer returned by malloc
is not appropriately aligned. (On most implementations, the UB
doesn't do anything bad; the misaligned pointer value is simply
stored in p.)
The behavior isn't *always* undefined. The pointer returned by
malloc(1) could be appropriately aligned (always or just in this
one instance), or long double could have an alignment of 1 byte.
--
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 | cross@spitfire.i.gajendra.net (Dan Cross) |
|---|---|
| Date | 2026-10-16 03:09 +0000 |
| Message-ID | <11as4h9$7ht$1@reader2.panix.com> |
| In reply to | #403200 |
In article <11arlj9$2q39c$1@kst.eternal-september.org>, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote: >cross@spitfire.i.gajendra.net (Dan Cross) writes: >> In article <11ap0fo$1t8gq$2@kst.eternal-september.org>, >> Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote: >> >[snip] >> Somewhat informally, the C17 wording could be read as requiring >> that the pointer returned from `malloc` must be suitable for >> assignment to any pointer to a type with `alignof(max_align_t)` >> regardless of the requested size, which might be smaller. N2293 >> calls this the, '"strong-alignment" reading.' > >The C17 wording is: > > The pointer returned if the allocation succeeds is suitably aligned > so that it may be assigned to a pointer to any type of object with a > fundamental alignment requirement and then used to access such an > object or an array of such objects in the space allocated (until the > space is explicitly deallocated). > >I don't see any other way to interpret that. Nor do I, but N2293 says that some implementers did. Here's how David Goldblatt explains it: |The current wording | |C17, 7.22.3 states: "The pointer returned if the allocation |succeeds is suitably aligned so that it may be assigned to a |pointer to any type of object with a fundamental alignment |requirement and then used to access such an object or an array |of such objects in the space allocated". | |The two clauses of interest here are "it may be assigned to a |pointer to any type of object with a fundamental alignment |requirement" and "and then used to access such an object or an |array of such objects in the space allocated". Strong-alignment |readers tend to see both clauses as independent, whereas |weak-alignment readers tend to see the second as an adverbial |clause modifying the first. Neither reading is completely |satisfactory. The strong-alignment view implies an independent |clause with a tense mismatch or a missing verb; the |weak-alignment view uses "and then" when "then" would suffice, |which could imply a sequencing at odds with the interpretation. I don't see it, myself, and I'm a "strong-alignment reader", but he goes on: |In the author's view, attempting to declare one of these two |parsings correct is a waste of time. Many different |implementers, fluent in English and acting in good faith, have |parsed the sentence both ways. The question is how to |reconcile the divergence. Indeed. >It requires that >a pointer returned by a successful malloc() must *always* be >suitably aligned. A pointer returned by malloc(1) must be aligned >so that it can point to a long long, for example. > >It overlooks the fact that it can't point to a long long, because >there isn't room for it. And there's no portable way to tell if an >implementation violates this requirement. If an implementation's >malloc(1) returns an "odd" pointer, it violates the standard's >requirement, but that violation likely has no real effect. Agreed. >For C23, it was recognized that requiring strict alignment for >tiny allocations is neither useful nor necessarily meaningful. >malloc(1) might as well be allowed to return an "odd" pointer. Yes. >>>[snip] >>>If you allow an object type to have an alignment greater than its >>>size, then the ambiguity can result in an actual difference in the >>>requirements. But then arrays don't work. >> >> That's ok; this is only about the properties vis alignment of >> the pointer returned from malloc. Consider x86_64 with the >> System V ABI again or ARM64 with the AAPCS; suppose that >> `char *p = malloc(char[3]);` assigns a non-NULL ponter to `p`. > >Alas, that's a syntax error. The argument to malloc is an expression, >not a type. (I'm certain you knew that.) Indeed; I meant to write, `malloc(sizeof(char[3]))` but as you correctly surmised, I mistyped. >You can write >`malloc(sizeof (char[3])`, but that's just malloc(3); no type >information is passed. > >And the alignment of char[3] is 1. An array of two char[3] objects has >a size of 6; there are no alignment gaps between the elements. Right. The only reason I wanted to write it that way was to drive that point home; in the "strong-alignment" reading, for small allocations, the alignment of the address the pointer returned from `malloc` refers to is totally decoupled from the requested size: `sizeof(char[3])` is three, which reflects the fundamental alignment requirement of `char[3]` being 1; because `malloc` doesn't know whether the resulting allocation will be used to store something with a fundamental alignment criteria of two or not (assuming such a type exists in the implementation), it must return a pointer to an address that is at least aligned to an even boundary. In any event, whether `malloc` must return something with stronger alignment, or merely can at its own convenience, is the interesting high order bit here. But, you know, I can't type so flubbed the example. :-D >> The question is only whether or not the address `p` refers to is >> required to be aligned on a 16-byte boundary; under the >> '"strong-alignment" reading' in N2293, it is, even though the >> allocated size is only 3. Under the '"weak-alignment" reading', >> the return address can aligned on an even boundary, and C23 >> codified the weak-alignment reading. Note that neither reading >> says anything about the size of elements or their alignment in >> an allocation that is treated like an array; it only affects >> the alignment of the starting address. > >Under C17, the result of malloc(3) must be strongly aligned (8 >bytes, for example). Under C23, it has to be at least 2 if there >are any types with 2-byte alignment. Yes, that's my interpretation. >> N2293 mentions this, but it probably bears repeating here: the >> utility of forcing `malloc` to align small allocations to e.g., >> `alignof(max_align_t)` seems mostly restricted to having some >> hope of overloading the low bits of the returned address for >> some program-specific purpose, which is how this came up in the >> first place in this thread. > >It hadn't occurred to me that that might be the reason. I assumed >it was just because strong alignment for small allocations is not >useful and should not be required. Allocating single bytes for >malloc(1) calls could have real advantages for some programs, and >the standard shouldn't prohibit that. N2293 says that existing implementations differed; Goldblatt gives a fairly concise list of major implementations and which does what. David Goldblatt is one of the maintainers of `jemalloc`, and probably cares about the space efficiency of small allocations; I suspect that motivated researching the differing interpretations and became the real motivation. It came up in this thread specifically because of discussions around stealing the low bits from the integer representation of a pointer. >As I recall, there was a discussion about reusing low-order bits of >pointers, and the fact that malloc(1) no longer has to be strongly >aligned became relevant to that. It doesn't imply that that was >the reason. See above. I suspect Goldblatt wanted to reconcile the different interpretations so that the `jemalloc` behavior could be considering conformant with the standard. >There might be an ambiguity in the English grammar of the C23 >statement about the alignment of malloc()ed pointers, but I don't >*think* we've seen a case where the two (or more?) different >interpretations actually lead to different semantics. I suppose it depends on which semantics you mean. There are definitely implementations that the "weak-alignment" reading and others that take the "strong-alignment" reading. **On those latter implementations**, assuming `malloc` of some small size is successful, you can almost certainly cast the resulting pointer to `uintptr_t` and use the low bits of the result for stuff, whereas on the former implementations, you can't, unless you know that the fundamental alignment requirement for the size you request is sufficiently large so that the low bits will be clear; for `malloc(1)` it basically won't be. >> As has already been mentioned, the >> standard makes no guarnatee about the integer representation of >> addresses, so this is already somewhat fraught, but on many >> platforms we may assume that as a practical matter, for a >> pointer to a suitably aligned address, those bits will be clear >> as a practical matter; I suppose if one wants that for a small >> allocation, use `aligned_alloc`. Caveat emptor. > >Yes, if you need aligned pointers, aligned_alloc() is the way to >get them. aligned_alloc(8, 1) gives you an 8-byte aligned pointer >to a 1-byte object; if that's useful, it's because you're doing >something weird. And if you need to fiddle with the low-order >bits of aligned pointers, you could run into the problems we've >already discussed. Yup. Agreed on all counts. There _are_ some valid uses for stealing low bits, but they're pretty esoteric; for instance, this: https://dl.acm.org/doi/10.1145/3731569.3764807 But if someone is dabbling in those dark magicks, they'd better know just exactly what they're doing. - Dan C.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2026-10-15 21:34 -0700 |
| Message-ID | <11as9gl$2vtou$1@kst.eternal-september.org> |
| In reply to | #403204 |
cross@spitfire.i.gajendra.net (Dan Cross) writes:
[Snip stuff I agree with]
> Right. The only reason I wanted to write it that way was to
> drive that point home; in the "strong-alignment" reading, for
> small allocations, the alignment of the address the pointer
> returned from `malloc` refers to is totally decoupled from the
> requested size: `sizeof(char[3])` is three, which reflects the
> fundamental alignment requirement of `char[3]` being 1; because
> `malloc` doesn't know whether the resulting allocation will be
> used to store something with a fundamental alignment criteria of
> two or not (assuming such a type exists in the implementation),
> it must return a pointer to an address that is at least aligned
> to an even boundary. In any event, whether `malloc` must return
> something with stronger alignment, or merely can at its own
> convenience, is the interesting high order bit here.
Just to avoid any misunderstanding, you refer to "the fundamental
alignment requirement of `char[3]` being 1".
The phrase "fundamental alignment requirement" might be misleading.
It could imply to someone unfamiliar with the terminology that
char[3] could have a fundamental alignment requirement and a
differing non-fundamental alignment requirement. (I had thought
the term "fundamental alignment" was new in C23, but it was added
in C11.)
It's possible that I'm the only one who thought this might be
confusing. If so, ignore this.
To over-explain: Each object type has an alignment, which is an integer
value.
A *fundamental alignment* is a valid alignment less than or equal to
alignof(max_align_t).
An *extended alignment* is represented by an alignment greater than
alignof(max_align_t).
As far as the language is concerned `char[3]` has an alignment of
1, and that alignment happens to be a fundamental alignment. (A
compiler might allocate standalone `char[3]` objects at a stricter
alignment, but the standard doesn't address that; compilers can
over-align anything they like.)
Which might be part of the confusion about the malloc() wording in C23.
The pointer returned if the allocation succeeds is suitably aligned
so that it may be assigned to a pointer to any type of object with a
fundamental alignment requirement and size less than or equal to the
size requested.
I read the phrase "with a fundamental alignment requirement" as a
predicate. A type has a fundamental alignment requirement or it
doesn't.
The alternative reading is "with a fundamental alignment requirement
(and size) less than or equal to the size requested", which says that
the alignment requirement (a) is fundamental *and* (b) is less than or
equal to the size requested. I think that's a rather strained
interpretation -- and I can't think of any cases where the distinction
between the two readings of the C23 wording could be significant, given
that an object type can't have an alignment bigger than its size.
[Snip more stuff I agree with]
--
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 4 of 5 — ← Prev page 1 2 3 [4] 5 Next page →
Back to top | Article view | comp.lang.c
csiph-web