• Re: What is wrong with malloc?

    From Keith Thompson@Keith.S.Thompson+u@gmail.com to comp.lang.c on Wed Jan 8 12:20:05 2025
    From Newsgroup: comp.lang.c

    Phillip <nntp@fulltermprivacy.com> writes:
    [...]
    C89 and C90 are better for 8-bit systems then C99 and newer. Not that
    you can't do 8-bit on C99 but it's just not designed as well for it
    since C99 assumes you've moved on to at least 16-bit.

    There were no changes in the sizes of the integer types from C89/C90 to
    C99, aside from the addition of long long. (And an implementation with
    8-bit int would be non-conforming under any edition of the standard,
    though it might be useful.)

    Perhaps some C89/C90 implementations are better for 8-bit systems than
    some C90 implementations?
    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Keith Thompson@Keith.S.Thompson+u@gmail.com to comp.lang.c on Wed Jan 8 12:25:18 2025
    From Newsgroup: comp.lang.c

    James Kuyper <jameskuyper@alumni.caltech.edu> writes:
    On 1/8/25 09:42, Julio Di Egidio wrote:
    On 08/01/2025 09:46, David Brown wrote:
    ...
    People who say they want to write strictly
    standards-conforming code, especially C90, so that it will run
    everywhere, misunderstand the relationship between the C standards and
    real-world tools.

    So, now that I have qualified it with "any device coming with a C
    compiler (that is not too broken)", would you think coding it in "ANSI
    C" makes some sense?

    I would agree with what you wrote, but probably not with what you meant.
    The first C standard, C89, was approved by ANSI. Later on, almost
    exactly the same standard was approved as C90 by ISO. They had to add
    three sections at the beginning to meet ISO requirements on how
    standards are organized. The result is that every section number from
    C89 corresponds to a section number 3 higher in C90.
    Since that time, every new version of the C standard has first been
    adopted by ISO, and then approved without changes by ANSI. Both
    organizations have a policy that the new version of a standard replaces
    the old one, which is no longer in effect. Therefore, ANSI C should, properly, refer to the current latest version of C that has been adopted
    by ANSI, which is C2023. I suspect that you were using "ANSI C" to refer
    to C89.

    Agreed -- but the term "ANSI C", though it logically should refer to C23
    (I presume ANSI has adopted it by now), is almost universally understood
    to refer to C89/C90. See, for example, gcc's "-ansi" option. <OT>For
    g++, "-ansi" means "-std=c++98" or "-std=c++03".</OT>

    I find it's best to avoid any ambiguity and avoid the term "ANSI C", and instead refer to ISO C90, C99, C11, etc.
    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Phillip@nntp@fulltermprivacy.com to comp.lang.c on Wed Jan 8 15:27:18 2025
    From Newsgroup: comp.lang.c

    On 1/8/25 3:20 PM, Keith Thompson wrote:
    Phillip <nntp@fulltermprivacy.com> writes:
    [...]
    C89 and C90 are better for 8-bit systems then C99 and newer. Not that
    you can't do 8-bit on C99 but it's just not designed as well for it
    since C99 assumes you've moved on to at least 16-bit.

    There were no changes in the sizes of the integer types from C89/C90 to
    C99, aside from the addition of long long. (And an implementation with
    8-bit int would be non-conforming under any edition of the standard,
    though it might be useful.)



    Perhaps some C89/C90 implementations are better for 8-bit systems than
    some C90 implementations?


    Yes, this is what I was saying.
    --
    Phillip Frabott
    ----------
    - Adam: Is a void really a void if it returns?
    - Jack: No, it's just nullspace at that point.
    ----------
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Keith Thompson@Keith.S.Thompson+u@gmail.com to comp.lang.c on Wed Jan 8 13:41:43 2025
    From Newsgroup: comp.lang.c

    Phillip <nntp@fulltermprivacy.com> writes:
    On 1/8/25 3:20 PM, Keith Thompson wrote:
    Phillip <nntp@fulltermprivacy.com> writes:
    [...]
    C89 and C90 are better for 8-bit systems then C99 and newer. Not that
    you can't do 8-bit on C99 but it's just not designed as well for it
    since C99 assumes you've moved on to at least 16-bit.
    There were no changes in the sizes of the integer types from C89/C90
    to
    C99, aside from the addition of long long. (And an implementation with
    8-bit int would be non-conforming under any edition of the standard,
    though it might be useful.)

    Perhaps some C89/C90 implementations are better for 8-bit systems than
    some C90 implementations?

    Yes, this is what I was saying.

    I'm curious about the details. What C89/C90 implementation are
    you using, and what features make it more suitable for 8-bit
    systems? (Any useful extensions could be applied to a C99 or
    later implementation. It sounds like the implementer just hasn't
    done that.)
    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Keith Thompson@Keith.S.Thompson+u@gmail.com to comp.lang.c on Wed Jan 8 14:12:43 2025
    From Newsgroup: comp.lang.c

    David Brown <david.brown@hesbynett.no> writes:
    [...]
    There are basically two classes of small embedded devices - those that
    are usually programmed with gcc (and sometimes clang, and occasionally
    vastly expensive commercial tools), and those that are programmed
    using non-standard, limited and often expensive sort-of-C compilers.
    For people using gcc, clang, Green Hills, Code Warrior, or other
    quality tools on a 16-bit or 32-bit microcontroller, C99 is not a
    problem. C23 is not a problem for the most popular toolchain for the
    most popular microcontroller core.
    [...]

    It's also worth mentioning that the standard specifies two kinds of implementations, "hosted" and "freestanding".

    A hosted implementation must provide the entire standard library (except
    for parts that are explicitly optional). The program entry point is
    "main". Larger embedded systems (for example, Linux-based systems)
    often have "hosted" implementations.

    In a freestanding implementation, most of the standard library need not
    be provided. Library facilities are implementation-defined, as is the
    program entry point. Freestanding implementations generally target
    systems with no operating system. There might not be a malloc()
    function.
    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c on Wed Jan 8 15:00:07 2025
    From Newsgroup: comp.lang.c

    On 1/8/2025 2:12 PM, Keith Thompson wrote:
    David Brown <david.brown@hesbynett.no> writes:
    [...]
    There are basically two classes of small embedded devices - those that
    are usually programmed with gcc (and sometimes clang, and occasionally
    vastly expensive commercial tools), and those that are programmed
    using non-standard, limited and often expensive sort-of-C compilers.
    For people using gcc, clang, Green Hills, Code Warrior, or other
    quality tools on a 16-bit or 32-bit microcontroller, C99 is not a
    problem. C23 is not a problem for the most popular toolchain for the
    most popular microcontroller core.
    [...]

    It's also worth mentioning that the standard specifies two kinds of implementations, "hosted" and "freestanding".

    A hosted implementation must provide the entire standard library (except
    for parts that are explicitly optional). The program entry point is
    "main". Larger embedded systems (for example, Linux-based systems)
    often have "hosted" implementations.

    In a freestanding implementation, most of the standard library need not
    be provided. Library facilities are implementation-defined, as is the program entry point. Freestanding implementations generally target
    systems with no operating system. There might not be a malloc()
    function.


    A long time ago (several decades) I was working with a system that had
    no malloc. Iirc, it was a version of Quadros.
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Phillip@nntp@fulltermprivacy.com to comp.lang.c on Thu Jan 9 00:09:31 2025
    From Newsgroup: comp.lang.c

    On 1/8/25 4:41 PM, Keith Thompson wrote:
    Phillip <nntp@fulltermprivacy.com> writes:
    On 1/8/25 3:20 PM, Keith Thompson wrote:
    Phillip <nntp@fulltermprivacy.com> writes:
    [...]
    C89 and C90 are better for 8-bit systems then C99 and newer. Not that
    you can't do 8-bit on C99 but it's just not designed as well for it
    since C99 assumes you've moved on to at least 16-bit.
    There were no changes in the sizes of the integer types from C89/C90
    to
    C99, aside from the addition of long long. (And an implementation with
    8-bit int would be non-conforming under any edition of the standard,
    though it might be useful.)

    Perhaps some C89/C90 implementations are better for 8-bit systems than
    some C90 implementations?

    Yes, this is what I was saying.

    I'm curious about the details. What C89/C90 implementation are
    you using, and what features make it more suitable for 8-bit
    systems? (Any useful extensions could be applied to a C99 or
    later implementation. It sounds like the implementer just hasn't
    done that.)


    Generally this only applies to use cases where specific instructions
    generated by the compiler are different between c90 and c99 where TOE's
    matter (timing of execution). For example, there are cases (sorry I
    don't have examples because it's been a long time since I've gone
    through this) where c99, in order to be more efficient, will output a different set of instructions, but in certain cases, those instructions,
    while more efficient, take longer to process on the CPU or
    microcontroller. Whereas C89 and C90 may be more inefficient but the instructions execute faster. It might only be that C99 adds an extra 1-3
    clock cycles, and in most cases this isn't a problem or noticeable. But
    when you are dealing with devices that are responsible for keeping a
    human alive (such as a pace maker) the extra cycles can add up over time
    and will cause trouble down the road. So this was the purpose behind my
    point of reference earlier was just to say, that there are niche cases
    where the statement that was made, wouldn't be accurate.

    For pace makers the GNU GCC implementation was used and for the smart prosthetic the CLANG implementation was used. GCC was using C90 and
    CLANG was using C89 (ANSI).

    Although above I couldn't provide a specific example (again sorry about
    that) I do have the result report from back when I was testing out pace
    makers with C99 over C90 (2007) and the process found that with C99 the processor would be behind by around 500 cycles within 19h 41m 19s from
    program start. This had a +/- of 12 cycles differential with repeat
    testing. That would mean the heart would miss a beat ever 17 days.
    --
    Phillip Frabott
    ----------
    - Adam: Is a void really a void if it returns?
    - Jack: No, it's just nullspace at that point.
    ----------
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Keith Thompson@Keith.S.Thompson+u@gmail.com to comp.lang.c on Wed Jan 8 21:34:37 2025
    From Newsgroup: comp.lang.c

    Phillip <nntp@fulltermprivacy.com> writes:
    On 1/8/25 4:41 PM, Keith Thompson wrote:
    Phillip <nntp@fulltermprivacy.com> writes:
    On 1/8/25 3:20 PM, Keith Thompson wrote:
    Phillip <nntp@fulltermprivacy.com> writes:
    [...]
    C89 and C90 are better for 8-bit systems then C99 and newer. Not that >>>>> you can't do 8-bit on C99 but it's just not designed as well for it
    since C99 assumes you've moved on to at least 16-bit.
    There were no changes in the sizes of the integer types from C89/C90
    to
    C99, aside from the addition of long long. (And an implementation with >>>> 8-bit int would be non-conforming under any edition of the standard,
    though it might be useful.)

    Perhaps some C89/C90 implementations are better for 8-bit systems than >>>> some C90 implementations?

    Yes, this is what I was saying.
    I'm curious about the details. What C89/C90 implementation are
    you using, and what features make it more suitable for 8-bit
    systems? (Any useful extensions could be applied to a C99 or
    later implementation. It sounds like the implementer just hasn't
    done that.)

    Generally this only applies to use cases where specific instructions generated by the compiler are different between c90 and c99 where
    TOE's matter (timing of execution). For example, there are cases
    (sorry I don't have examples because it's been a long time since I've
    gone through this) where c99, in order to be more efficient, will
    output a different set of instructions, but in certain cases, those instructions, while more efficient, take longer to process on the CPU
    or microcontroller. Whereas C89 and C90 may be more inefficient but
    the instructions execute faster. It might only be that C99 adds an
    extra 1-3 clock cycles, and in most cases this isn't a problem or
    noticeable. But when you are dealing with devices that are responsible
    for keeping a human alive (such as a pace maker) the extra cycles can
    add up over time and will cause trouble down the road. So this was the purpose behind my point of reference earlier was just to say, that
    there are niche cases where the statement that was made, wouldn't be accurate.

    Are you saying that, for example, "gcc -std=c90" and "gcc -std=c99"
    are generating different instruction sequences for the same code,
    with the same version of gcc in both cases?

    Hmm. I can't think of anything in the changes from C90 to C99 that
    would necessarily cause that kind of thing. Unless I'm missing
    something, it's not C99 that results in the "more efficient"
    instructions, it's the behavior of the compiler in C99 mode.
    It could as easily have been the other way around.

    For pace makers the GNU GCC implementation was used and for the smart prosthetic the CLANG implementation was used. GCC was using C90 and
    CLANG was using C89 (ANSI).

    Note that C89 and C90 are exactly the same language. The 1990 ISO C
    standard is identical to the C89 standard, except for some introductory sections introduced by ISO. (I've heard vague rumors of some other differences, but as far as I know there's nothing significant.)

    Although above I couldn't provide a specific example (again sorry
    about that) I do have the result report from back when I was testing
    out pace makers with C99 over C90 (2007) and the process found that
    with C99 the processor would be behind by around 500 cycles within 19h
    41m 19s from program start. This had a +/- of 12 cycles differential
    with repeat testing. That would mean the heart would miss a beat ever
    17 days.
    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Thu Jan 9 14:53:56 2025
    From Newsgroup: comp.lang.c

    On 09/01/2025 06:09, Phillip wrote:
    On 1/8/25 4:41 PM, Keith Thompson wrote:
    Phillip <nntp@fulltermprivacy.com> writes:
    On 1/8/25 3:20 PM, Keith Thompson wrote:
    Phillip <nntp@fulltermprivacy.com> writes:
    [...]
    C89 and C90 are better for 8-bit systems then C99 and newer. Not that >>>>> you can't do 8-bit on C99 but it's just not designed as well for it
    since C99 assumes you've moved on to at least 16-bit.
    There were no changes in the sizes of the integer types from C89/C90
    to
    C99, aside from the addition of long long.  (And an implementation with >>>> 8-bit int would be non-conforming under any edition of the standard,
    though it might be useful.)

    Perhaps some C89/C90 implementations are better for 8-bit systems than >>>> some C90 implementations?

    Yes, this is what I was saying.

    I'm curious about the details.  What C89/C90 implementation are
    you using, and what features make it more suitable for 8-bit
    systems?  (Any useful extensions could be applied to a C99 or
    later implementation.  It sounds like the implementer just hasn't
    done that.)


    Generally this only applies to use cases where specific instructions generated by the compiler are different between c90 and c99 where TOE's matter (timing of execution). For example, there are cases (sorry I
    don't have examples because it's been a long time since I've gone
    through this) where c99, in order to be more efficient, will output a different set of instructions, but in certain cases, those instructions, while more efficient, take longer to process on the CPU or
    microcontroller. Whereas C89 and C90 may be more inefficient but the instructions execute faster. It might only be that C99 adds an extra 1-3 clock cycles, and in most cases this isn't a problem or noticeable. But
    when you are dealing with devices that are responsible for keeping a
    human alive (such as a pace maker) the extra cycles can add up over time
    and will cause trouble down the road. So this was the purpose behind my point of reference earlier was just to say, that there are niche cases
    where the statement that was made, wouldn't be accurate.

    For pace makers the GNU GCC implementation was used and for the smart prosthetic the CLANG implementation was used. GCC was using C90 and
    CLANG was using C89 (ANSI).

    Although above I couldn't provide a specific example (again sorry about that) I do have the result report from back when I was testing out pace makers with C99 over C90 (2007) and the process found that with C99 the processor would be behind by around 500 cycles within 19h 41m 19s from program start. This had a +/- of 12 cycles differential with repeat
    testing. That would mean the heart would miss a beat ever 17 days.


    I'm sorry, none of that makes /any/ sense at all to me.

    Different compilers and different compiler versions may emit different instructions with different timings - that is independent of the C
    standard version. There is almost no code you can write that is valid
    C89/C90 (C89 so-called "ANSI C" and C90 ISO C are identical apart from
    the numbering of the chapters) and also valid C99, but that has
    different semantics. There were changes in the types of certain integer constants, and division in C99 with negative values is defined to be
    "truncate towards zero", while in C90 an implementation could
    alternatively choose "truncate towards negative infinity". However, it
    is highly unlikely that a single compiler that supports both C90 and C99
    modes would use different signed integer algorithms in the different modes.

    It sounds more likely that you are simply using different compilers -
    and then it is not surprising that there are differences in the
    generated instructions. It's like comparing a green car with a red bus
    and concluding that green things go faster than red things.

    I also note that you earlier said you used a 6502 on these devices -
    neither gcc nor clang have ever supported the 6502 as a target.

    And if your pacemaker is relying on the timing of instructions generated
    by a C compiler for the timing of heart beats, then you are doing the
    whole thing /completely/ wrong. It doesn't matter what compiler and
    what language you are using, that's not how you handle important timing
    in embedded systems.

    Then you talk about missing a heart beat every 17 days. I presume you
    realise how absurd that is? Just considering the timing alone, that's a accuracy of about 0.7 ppm (parts per million) - about a thousand times
    more accurate than common oscillators used with small microcontrollers.
    It takes a fairly sophisticated and expensive timing circuit to reach
    those levels (though in a pacemaker you have the benefit of a stable environment temperature). But this is not just measuring time for the
    sake of it - you are talking about heart beats. If your system is
    running 0.7 ppm slower than before, the heart will not skip beats - it
    will beat at a rate 0.7 ppm slower, and that will make not the slightest difference. I am not a doctor (though I have worked on heart rate
    measurement devices), but I would not expect any medically significant differences before you were at least a few percent out on the timing.
    In a normal healthy heart, beat-to-beat variation can be 10% while still considered "normal". In fact, if it is /not/ varying by a few percent,
    it's an indication of serious health problems.


    But I don't expect anyone will want to use AVL trees in a pacemaker
    anyway :-)

    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Thu Jan 9 14:58:25 2025
    From Newsgroup: comp.lang.c

    On 08/01/2025 23:12, Keith Thompson wrote:
    David Brown <david.brown@hesbynett.no> writes:
    [...]
    There are basically two classes of small embedded devices - those that
    are usually programmed with gcc (and sometimes clang, and occasionally
    vastly expensive commercial tools), and those that are programmed
    using non-standard, limited and often expensive sort-of-C compilers.
    For people using gcc, clang, Green Hills, Code Warrior, or other
    quality tools on a 16-bit or 32-bit microcontroller, C99 is not a
    problem. C23 is not a problem for the most popular toolchain for the
    most popular microcontroller core.
    [...]

    It's also worth mentioning that the standard specifies two kinds of implementations, "hosted" and "freestanding".


    Yes - I mentioned that in one of my posts. It is quite common for
    compilers for embedded systems to be missing a few standard library
    features (such as support for locales or wide characters), to have
    limited features (such as printf / scanf implementations without
    floating point, to reduce the code size), and to have somewhat odd system-specific implementations of things like file and stream IO functions.

    However, all embedded toolchains I have ever used implement a
    substantial part of the standard library - pretty much everything that
    can reasonably be implemented and used on the embedded targets.

    A hosted implementation must provide the entire standard library (except
    for parts that are explicitly optional). The program entry point is
    "main". Larger embedded systems (for example, Linux-based systems)
    often have "hosted" implementations.

    In a freestanding implementation, most of the standard library need not
    be provided. Library facilities are implementation-defined, as is the program entry point. Freestanding implementations generally target
    systems with no operating system. There might not be a malloc()
    function.


    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Michael S@already5chosen@yahoo.com to comp.lang.c on Thu Jan 9 17:27:31 2025
    From Newsgroup: comp.lang.c

    On Thu, 9 Jan 2025 14:53:56 +0100
    David Brown <david.brown@hesbynett.no> wrote:
    On 09/01/2025 06:09, Phillip wrote:
    On 1/8/25 4:41 PM, Keith Thompson wrote:
    Phillip <nntp@fulltermprivacy.com> writes:
    On 1/8/25 3:20 PM, Keith Thompson wrote:
    Phillip <nntp@fulltermprivacy.com> writes:
    [...]
    C89 and C90 are better for 8-bit systems then C99 and newer.
    Not that you can't do 8-bit on C99 but it's just not designed
    as well for it since C99 assumes you've moved on to at least
    16-bit.
    There were no changes in the sizes of the integer types from
    C89/C90 to
    C99, aside from the addition of long long.  (And an
    implementation with 8-bit int would be non-conforming under any
    edition of the standard, though it might be useful.)

    Perhaps some C89/C90 implementations are better for 8-bit
    systems than some C90 implementations?

    Yes, this is what I was saying.

    I'm curious about the details.  What C89/C90 implementation are
    you using, and what features make it more suitable for 8-bit
    systems?  (Any useful extensions could be applied to a C99 or
    later implementation.  It sounds like the implementer just hasn't
    done that.)


    Generally this only applies to use cases where specific
    instructions generated by the compiler are different between c90
    and c99 where TOE's matter (timing of execution). For example,
    there are cases (sorry I don't have examples because it's been a
    long time since I've gone through this) where c99, in order to be
    more efficient, will output a different set of instructions, but in
    certain cases, those instructions, while more efficient, take
    longer to process on the CPU or microcontroller. Whereas C89 and
    C90 may be more inefficient but the instructions execute faster. It
    might only be that C99 adds an extra 1-3 clock cycles, and in most
    cases this isn't a problem or noticeable. But when you are dealing
    with devices that are responsible for keeping a human alive (such
    as a pace maker) the extra cycles can add up over time and will
    cause trouble down the road. So this was the purpose behind my
    point of reference earlier was just to say, that there are niche
    cases where the statement that was made, wouldn't be accurate.

    For pace makers the GNU GCC implementation was used and for the
    smart prosthetic the CLANG implementation was used. GCC was using
    C90 and CLANG was using C89 (ANSI).

    Although above I couldn't provide a specific example (again sorry
    about that) I do have the result report from back when I was
    testing out pace makers with C99 over C90 (2007) and the process
    found that with C99 the processor would be behind by around 500
    cycles within 19h 41m 19s from program start. This had a +/- of 12
    cycles differential with repeat testing. That would mean the heart
    would miss a beat ever 17 days.

    I'm sorry, none of that makes /any/ sense at all to me.

    Different compilers and different compiler versions may emit
    different instructions with different timings - that is independent
    of the C standard version. There is almost no code you can write
    that is valid C89/C90 (C89 so-called "ANSI C" and C90 ISO C are
    identical apart from the numbering of the chapters) and also valid
    C99, but that has different semantics. There were changes in the
    types of certain integer constants, and division in C99 with negative
    values is defined to be "truncate towards zero", while in C90 an implementation could alternatively choose "truncate towards negative infinity". However, it is highly unlikely that a single compiler
    that supports both C90 and C99 modes would use different signed
    integer algorithms in the different modes.

    It sounds more likely that you are simply using different compilers -
    and then it is not surprising that there are differences in the
    generated instructions. It's like comparing a green car with a red
    bus and concluding that green things go faster than red things.

    I also note that you earlier said you used a 6502 on these devices -
    neither gcc nor clang have ever supported the 6502 as a target.

    And if your pacemaker is relying on the timing of instructions
    generated by a C compiler for the timing of heart beats, then you are
    doing the whole thing /completely/ wrong. It doesn't matter what
    compiler and what language you are using, that's not how you handle
    important timing in embedded systems.

    Then you talk about missing a heart beat every 17 days. I presume
    you realise how absurd that is? Just considering the timing alone,
    that's a accuracy of about 0.7 ppm (parts per million) - about a
    thousand times more accurate than common oscillators used with small microcontrollers.
    Off topic nitpick:
    0.7 ppm * 1000 = 700ppm.
    Last time I looked, 50-70 ppm crystal oscillators were cheaper than less precise parts.
    Alternatively for cheap crystal-less clock source the expected
    precision is closer to 7000 ppm than 700.
    It takes a fairly sophisticated and expensive
    timing circuit to reach those levels (though in a pacemaker you have
    the benefit of a stable environment temperature). But this is not
    just measuring time for the sake of it - you are talking about heart
    beats. If your system is running 0.7 ppm slower than before, the
    heart will not skip beats - it will beat at a rate 0.7 ppm slower,
    and that will make not the slightest difference. I am not a doctor
    (though I have worked on heart rate measurement devices), but I would
    not expect any medically significant differences before you were at
    least a few percent out on the timing. In a normal healthy heart, beat-to-beat variation can be 10% while still considered "normal".
    In fact, if it is /not/ varying by a few percent, it's an indication
    of serious health problems.

    I tried to use provided numbers to estimate a clock rate of Phillip's processor. Got 10 KHz. I am aware of ultra-low-power CPUs that run at
    32KHz, but never encountered anything slower than that.

    But I don't expect anyone will want to use AVL trees in a pacemaker
    anyway :-)

    I like AVL trees. Not 100% sure how exactly I can apply them in pace
    makers, but I'd certainly try my best.
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Phillip@nntp@fulltermprivacy.com to comp.lang.c on Thu Jan 9 10:30:35 2025
    From Newsgroup: comp.lang.c

    On 1/9/25 12:34 AM, Keith Thompson wrote:
    Phillip <nntp@fulltermprivacy.com> writes:
    On 1/8/25 4:41 PM, Keith Thompson wrote:
    Phillip <nntp@fulltermprivacy.com> writes:
    On 1/8/25 3:20 PM, Keith Thompson wrote:
    Phillip <nntp@fulltermprivacy.com> writes:
    [...]
    C89 and C90 are better for 8-bit systems then C99 and newer. Not that >>>>>> you can't do 8-bit on C99 but it's just not designed as well for it >>>>>> since C99 assumes you've moved on to at least 16-bit.
    There were no changes in the sizes of the integer types from C89/C90 >>>>> to
    C99, aside from the addition of long long. (And an implementation with >>>>> 8-bit int would be non-conforming under any edition of the standard, >>>>> though it might be useful.)

    Perhaps some C89/C90 implementations are better for 8-bit systems than >>>>> some C90 implementations?

    Yes, this is what I was saying.
    I'm curious about the details. What C89/C90 implementation are
    you using, and what features make it more suitable for 8-bit
    systems? (Any useful extensions could be applied to a C99 or
    later implementation. It sounds like the implementer just hasn't
    done that.)

    Generally this only applies to use cases where specific instructions
    generated by the compiler are different between c90 and c99 where
    TOE's matter (timing of execution). For example, there are cases
    (sorry I don't have examples because it's been a long time since I've
    gone through this) where c99, in order to be more efficient, will
    output a different set of instructions, but in certain cases, those
    instructions, while more efficient, take longer to process on the CPU
    or microcontroller. Whereas C89 and C90 may be more inefficient but
    the instructions execute faster. It might only be that C99 adds an
    extra 1-3 clock cycles, and in most cases this isn't a problem or
    noticeable. But when you are dealing with devices that are responsible
    for keeping a human alive (such as a pace maker) the extra cycles can
    add up over time and will cause trouble down the road. So this was the
    purpose behind my point of reference earlier was just to say, that
    there are niche cases where the statement that was made, wouldn't be
    accurate.

    Are you saying that, for example, "gcc -std=c90" and "gcc -std=c99"
    are generating different instruction sequences for the same code,
    with the same version of gcc in both cases?


    Yes. And it did surprise me as well. But it got rejected by the medical association at the time because the cycle counts would get behind their requirements. When they sent it back I spent a month thinking it was my
    code before someone had suggested to try C90 (which I did) and it turned
    out that it actually did change the sequence just enough to make a
    difference. Without any code changes I resubmitted the C90 version (and
    ask them to do a second run of the C99 as well) and it turned out that
    it passed and the second round of tests on the C99 failed. After getting
    back both test binaries and disassembling them, I did find there were
    two different sequences between the C99 and C90. It was subtle but
    present. Enough to fail the test. Ever since then I've been using C90
    for pace makers.

    Hmm. I can't think of anything in the changes from C90 to C99 that
    would necessarily cause that kind of thing. Unless I'm missing
    something, it's not C99 that results in the "more efficient"
    instructions, it's the behavior of the compiler in C99 mode.
    It could as easily have been the other way around.


    The above includes a response to this.

    For pace makers the GNU GCC implementation was used and for the smart
    prosthetic the CLANG implementation was used. GCC was using C90 and
    CLANG was using C89 (ANSI).

    Note that C89 and C90 are exactly the same language. The 1990 ISO C
    standard is identical to the C89 standard, except for some introductory sections introduced by ISO. (I've heard vague rumors of some other differences, but as far as I know there's nothing significant.)


    I'm aware, I only stated it because you asked the question and I was
    being thorough.

    Although above I couldn't provide a specific example (again sorry
    about that) I do have the result report from back when I was testing
    out pace makers with C99 over C90 (2007) and the process found that
    with C99 the processor would be behind by around 500 cycles within 19h
    41m 19s from program start. This had a +/- of 12 cycles differential
    with repeat testing. That would mean the heart would miss a beat ever
    17 days.

    --
    Phillip Frabott
    ----------
    - Adam: Is a void really a void if it returns?
    - Jack: No, it's just nullspace at that point.
    ----------
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Michael S@already5chosen@yahoo.com to comp.lang.c on Thu Jan 9 18:12:44 2025
    From Newsgroup: comp.lang.c

    On Wed, 08 Jan 2025 21:34:37 -0800
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:

    Phillip <nntp@fulltermprivacy.com> writes:
    On 1/8/25 4:41 PM, Keith Thompson wrote:
    Phillip <nntp@fulltermprivacy.com> writes:
    On 1/8/25 3:20 PM, Keith Thompson wrote:
    Phillip <nntp@fulltermprivacy.com> writes:
    [...]
    C89 and C90 are better for 8-bit systems then C99 and newer.
    Not that you can't do 8-bit on C99 but it's just not designed
    as well for it since C99 assumes you've moved on to at least
    16-bit.
    There were no changes in the sizes of the integer types from
    C89/C90 to
    C99, aside from the addition of long long. (And an
    implementation with 8-bit int would be non-conforming under any
    edition of the standard, though it might be useful.)

    Perhaps some C89/C90 implementations are better for 8-bit
    systems than some C90 implementations?

    Yes, this is what I was saying.
    I'm curious about the details. What C89/C90 implementation are
    you using, and what features make it more suitable for 8-bit
    systems? (Any useful extensions could be applied to a C99 or
    later implementation. It sounds like the implementer just hasn't
    done that.)

    Generally this only applies to use cases where specific instructions generated by the compiler are different between c90 and c99 where
    TOE's matter (timing of execution). For example, there are cases
    (sorry I don't have examples because it's been a long time since
    I've gone through this) where c99, in order to be more efficient,
    will output a different set of instructions, but in certain cases,
    those instructions, while more efficient, take longer to process on
    the CPU or microcontroller. Whereas C89 and C90 may be more
    inefficient but the instructions execute faster. It might only be
    that C99 adds an extra 1-3 clock cycles, and in most cases this
    isn't a problem or noticeable. But when you are dealing with
    devices that are responsible for keeping a human alive (such as a
    pace maker) the extra cycles can add up over time and will cause
    trouble down the road. So this was the purpose behind my point of
    reference earlier was just to say, that there are niche cases where
    the statement that was made, wouldn't be accurate.

    Are you saying that, for example, "gcc -std=c90" and "gcc -std=c99"
    are generating different instruction sequences for the same code,
    with the same version of gcc in both cases?

    Hmm. I can't think of anything in the changes from C90 to C99 that
    would necessarily cause that kind of thing. Unless I'm missing
    something, it's not C99 that results in the "more efficient"
    instructions, it's the behavior of the compiler in C99 mode.
    It could as easily have been the other way around.

    For pace makers the GNU GCC implementation was used and for the
    smart prosthetic the CLANG implementation was used. GCC was using
    C90 and CLANG was using C89 (ANSI).

    Note that C89 and C90 are exactly the same language. The 1990 ISO C
    standard is identical to the C89 standard, except for some
    introductory sections introduced by ISO. (I've heard vague rumors of
    some other differences, but as far as I know there's nothing
    significant.)

    Although above I couldn't provide a specific example (again sorry
    about that) I do have the result report from back when I was testing
    out pace makers with C99 over C90 (2007) and the process found that
    with C99 the processor would be behind by around 500 cycles within
    19h 41m 19s from program start. This had a +/- of 12 cycles
    differential with repeat testing. That would mean the heart would
    miss a beat ever 17 days.


    The most likely difference is mentioned by David Brown in the post
    above.

    int div8(int x) { return x/8; }

    C90 compiler can turn a division into arithmetic right shift. C99
    compiler can not do it. If compiler wants to avoid division, it will
    have to generate more elaborate sequence.

    In case of gcc, it does not apply because gcc follows c99 rules
    regardless of requested language standard. But it can be the case for
    other compilers.




    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Phillip@nntp@fulltermprivacy.com to comp.lang.c on Thu Jan 9 12:40:46 2025
    From Newsgroup: comp.lang.c

    On 1/9/25 11:12 AM, Michael S wrote:
    On Wed, 08 Jan 2025 21:34:37 -0800
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:

    Phillip <nntp@fulltermprivacy.com> writes:
    On 1/8/25 4:41 PM, Keith Thompson wrote:
    Phillip <nntp@fulltermprivacy.com> writes:
    On 1/8/25 3:20 PM, Keith Thompson wrote:
    Phillip <nntp@fulltermprivacy.com> writes:
    [...]
    C89 and C90 are better for 8-bit systems then C99 and newer.
    Not that you can't do 8-bit on C99 but it's just not designed
    as well for it since C99 assumes you've moved on to at least
    16-bit.
    There were no changes in the sizes of the integer types from
    C89/C90 to
    C99, aside from the addition of long long. (And an
    implementation with 8-bit int would be non-conforming under any
    edition of the standard, though it might be useful.)

    Perhaps some C89/C90 implementations are better for 8-bit
    systems than some C90 implementations?

    Yes, this is what I was saying.
    I'm curious about the details. What C89/C90 implementation are
    you using, and what features make it more suitable for 8-bit
    systems? (Any useful extensions could be applied to a C99 or
    later implementation. It sounds like the implementer just hasn't
    done that.)

    Generally this only applies to use cases where specific instructions
    generated by the compiler are different between c90 and c99 where
    TOE's matter (timing of execution). For example, there are cases
    (sorry I don't have examples because it's been a long time since
    I've gone through this) where c99, in order to be more efficient,
    will output a different set of instructions, but in certain cases,
    those instructions, while more efficient, take longer to process on
    the CPU or microcontroller. Whereas C89 and C90 may be more
    inefficient but the instructions execute faster. It might only be
    that C99 adds an extra 1-3 clock cycles, and in most cases this
    isn't a problem or noticeable. But when you are dealing with
    devices that are responsible for keeping a human alive (such as a
    pace maker) the extra cycles can add up over time and will cause
    trouble down the road. So this was the purpose behind my point of
    reference earlier was just to say, that there are niche cases where
    the statement that was made, wouldn't be accurate.

    Are you saying that, for example, "gcc -std=c90" and "gcc -std=c99"
    are generating different instruction sequences for the same code,
    with the same version of gcc in both cases?

    Hmm. I can't think of anything in the changes from C90 to C99 that
    would necessarily cause that kind of thing. Unless I'm missing
    something, it's not C99 that results in the "more efficient"
    instructions, it's the behavior of the compiler in C99 mode.
    It could as easily have been the other way around.

    For pace makers the GNU GCC implementation was used and for the
    smart prosthetic the CLANG implementation was used. GCC was using
    C90 and CLANG was using C89 (ANSI).

    Note that C89 and C90 are exactly the same language. The 1990 ISO C
    standard is identical to the C89 standard, except for some
    introductory sections introduced by ISO. (I've heard vague rumors of
    some other differences, but as far as I know there's nothing
    significant.)

    Although above I couldn't provide a specific example (again sorry
    about that) I do have the result report from back when I was testing
    out pace makers with C99 over C90 (2007) and the process found that
    with C99 the processor would be behind by around 500 cycles within
    19h 41m 19s from program start. This had a +/- of 12 cycles
    differential with repeat testing. That would mean the heart would
    miss a beat ever 17 days.


    The most likely difference is mentioned by David Brown in the post
    above.

    int div8(int x) { return x/8; }

    C90 compiler can turn a division into arithmetic right shift. C99
    compiler can not do it. If compiler wants to avoid division, it will
    have to generate more elaborate sequence.

    In case of gcc, it does not apply because gcc follows c99 rules
    regardless of requested language standard. But it can be the case for
    other compilers.





    I'd have to go back and look. There isn't that much division in pace
    makers but there is some nuance there that is likely the case for more
    then just division.
    --
    Phillip Frabott
    ----------
    - Adam: Is a void really a void if it returns?
    - Jack: No, it's just nullspace at that point.
    ----------
    --- Synchronet 3.20a-Linux NewsLink 1.114