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


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

AVL tree insertion - programming exercise

Started byTim Rentsch <tr.17687@z991.linuxsc.com>
First post2026-10-06 23:08 -0700
Last post2026-10-13 03:52 -0700
Articles 20 on this page of 96 — 20 participants

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


Contents

  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 →


#403106

Fromcross@spitfire.i.gajendra.net (Dan Cross)
Date2026-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]


#403108

FromDavid Brown <david.brown@hesbynett.no>
Date2026-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]


#403110

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2026-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]


#403124

Fromcross@spitfire.i.gajendra.net (Dan Cross)
Date2026-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]


#403134

From"chine.bleu" <chine.bleu@yahoo.com>
Date2026-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]


#403142

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2026-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]


#403145

FromDavid Brown <david.brown@hesbynett.no>
Date2026-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]


#403165

Fromcross@spitfire.i.gajendra.net (Dan Cross)
Date2026-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]


#403171

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2026-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]


#403178

FromDavid Brown <david.brown@hesbynett.no>
Date2026-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]


#403152

Fromcross@spitfire.i.gajendra.net (Dan Cross)
Date2026-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]


#403157

FromJanis Papanagnou <janis_papanagnou+ng@hotmail.com>
Date2026-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]


#403161

Fromcross@spitfire.i.gajendra.net (Dan Cross)
Date2026-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]


#403172

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2026-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]


#403188

Fromcross@spitfire.i.gajendra.net (Dan Cross)
Date2026-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]


#403200

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2026-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]


#403201

FromKaz Kylheku <046-301-5902@kylheku.com>
Date2026-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]


#403202

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2026-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]


#403204

Fromcross@spitfire.i.gajendra.net (Dan Cross)
Date2026-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]


#403205

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2026-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