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.
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.
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?
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 thatThere were no changes in the sizes of the integer types from C89/C90
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.
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.
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.
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.
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 thatThere were no changes in the sizes of the integer types from C89/C90
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.
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.)
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:I'm curious about the details. What C89/C90 implementation are
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 itThere were no changes in the sizes of the integer types from C89/C90
since C99 assumes you've moved on to at least 16-bit.
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.
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.
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 itThere were no changes in the sizes of the integer types from C89/C90
since C99 assumes you've moved on to at least 16-bit.
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.
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.
On 09/01/2025 06:09, Phillip wrote:Off topic nitpick:
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.There were no changes in the sizes of the integer types from
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.
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 :-)
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:I'm curious about the details. What C89/C90 implementation are
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.
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.
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:I'm curious about the details. What C89/C90 implementation are
Phillip <nntp@fulltermprivacy.com> writes:
[...]
C89 and C90 are better for 8-bit systems then C99 and newer.There were no changes in the sizes of the integer types from
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.
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.
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.
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:I'm curious about the details. What C89/C90 implementation are
Phillip <nntp@fulltermprivacy.com> writes:
[...]
C89 and C90 are better for 8-bit systems then C99 and newer.There were no changes in the sizes of the integer types from
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.
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.
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.
Sysop: | DaiTengu |
---|---|
Location: | Appleton, WI |
Users: | 1,007 |
Nodes: | 10 (0 / 10) |
Uptime: | 196:53:42 |
Calls: | 13,143 |
Files: | 186,574 |
D/L today: |
511 files (113M bytes) |
Messages: | 3,310,149 |