473,589 Members | 2,649 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Integer types in embedded systems


Let's say we had a simple function for returning the amount of days in
a month:

unsigned DaysInMonth(uns igned const month)
{
switch (month)
{
case 8:
case 3:
case 5:
case 10: return 30;

case 1: return 28;

default: return 31;
}
}

Notice the integer type I've used, i.e. "unsigned int" rather than
"unsigned char" or "unsigned short".

Many of the microcontroller s (i.e. a small chip that has a CPU and
RAM, basically it's a tiny little computer) in use nowadays do
arithmetic on 8-Bit numbers.

An example of a prevalent microcontroller nowadays would be the
PIC16F684. It's only got about 35 different CPU instructions. All of
the arithmetic instructions work on 8-Bit registers.

In my little code snippet above, the biggest number used is 31, which
of course would fit inside an "unsigned char".

In C, the plain "int" type is described as the "natural" type for the
system. I think a lot of people agree that this is the type you use
when you "just want to store a number", and I think a lot of people
expect it to be the fastest integer type.

The only problem with int, however, is that it must be at least 16-
Bit.

On an 8-Bit microcontroller such as the PIC16F684, this of course
means that int will NOT be the most efficient type. The problem with
this however is that we have code snippets like the one above that
think they're using the best integer types for the job. If we were to
re-write the code for an embedded system, we'd probably have:

char unsigned DaysInMonth(cha r unsigned const month)
{
switch (month)
{
case 8:
case 3:
case 5:
case 10: return 30;

case 1: return 28;

default: return 31;
}
}

I'd like now to bring up the topic of portable programming. In my own
code, I've begun to use types such as:

uint_fast8_t

Basically I'm saying "I want the fastest integer type whose range is
at least up to 255".

In this way, I can write code that will peform optimally on both
embedded systems and PC's.

To people out there who are enthusiastic about writing portable code,
do you think it's time we started using types like uint_fast8_t
instead of "unsigned int"?

Of course, even if our target platform doesn't supply an stdint.h, we
can always have a default version of it, e.g.:

typedef char unsigned uint_fast8_t;
or:
typedef unsigned uint_fast8_t;
Jun 27 '08 #1
30 4274
Tomás Ó hÉilidhe wrote:
PIC16F684. It's only got about 35 different CPU instructions.
I program that in assembly,
*because* it's only got about 35 different CPU instructions.
I've never felt any desire to use C on that chip.

do {
/*
** This whole loop is a single opcode on a PIC16F684
*/
} while (--n != 0);
To people out there who are enthusiastic about writing portable code,
do you think it's time we started using types like uint_fast8_t
instead of "unsigned int"?
--
pete
Jun 27 '08 #2
On Fri, 2 May 2008 13:42:23 -0700 (PDT), Tomás Ó hÉilidhe
<to*@lavabit.co mwrote in comp.lang.c:
>
Let's say we had a simple function for returning the amount of days in
a month:

unsigned DaysInMonth(uns igned const month)
First, omitting the "int", even if legal, is sloppy and would not
survive a code inspection in a professional organization.

Second, applying a const qualifier to a value parameter might pass a
code inspection, but is considered by many to be just plain prissy.
{
switch (month)
{
case 8:
case 3:
case 5:
case 10: return 30;

case 1: return 28;

default: return 31;
}
}

Notice the integer type I've used, i.e. "unsigned int" rather than
"unsigned char" or "unsigned short".

Many of the microcontroller s (i.e. a small chip that has a CPU and
RAM, basically it's a tiny little computer) in use nowadays do
arithmetic on 8-Bit numbers.

An example of a prevalent microcontroller nowadays would be the
PIC16F684. It's only got about 35 different CPU instructions. All of
the arithmetic instructions work on 8-Bit registers.
We won't get into many people's opinions about PICs, it would be
off-topic here.
In my little code snippet above, the biggest number used is 31, which
of course would fit inside an "unsigned char".
Which would, in C, immediately be promoted to either signed or
unsigned int. So you'd gain nothing. Some, perhaps many, embedded
compilers for 8-bit micros have an option for telling the compiler not
to promote 8-bit values. Once you do that, it's not really C anymore.
In C, the plain "int" type is described as the "natural" type for the
system. I think a lot of people agree that this is the type you use
when you "just want to store a number", and I think a lot of people
expect it to be the fastest integer type.
You seem to be a beginning embedded programmer, particularly based on
some of the posts you've made on comp.arch.embed ded. On the other
hand, you make these opinionated statements like "a lot of people
expect". Who are these people? How do you know what they expect?

I think that no experienced embedded programmer would expect that. I
think anyone who hasn't learned not to expect that does not have the
experience to professionally program embedded systems. And on
anything outside the embedded arena these days, they can get away with
expecting that.

Most C programmers these days are woefully ignorant, and they expect
many things, such as...

--a char is signed and has a range of [-128,127]

--an int is four bytes

--a pointer is four bytes

--a float is four bytes

--there is a stack

....an I could go on and on.
The only problem with int, however, is that it must be at least 16-
Bit.
Actually, that's not a problem. That's a guarantee and a good one.
On an 8-Bit microcontroller such as the PIC16F684, this of course
means that int will NOT be the most efficient type. The problem with
Actually, it generally is the most efficient type if you need a type
that can hold an object in either of the ranges [-32767,32767] or
[0,65535].
this however is that we have code snippets like the one above that
think they're using the best integer types for the job. If we were to
Your assumption is that they think that. Have you asked "they" what
they think, or are you just assuming?
re-write the code for an embedded system, we'd probably have:
Actually, speaking for more than 25 years of embedded system
development, I'd say they would most likely not rewrite the code,
Knuth being absolutely correct about premature optimization. Once the
program was finished and meeting its requirements, but needed a
performance boost, then it might possible be rewritten as you suggest
below. But only after a profiler or other hard measurement tool
proved that it was a bottleneck.
char unsigned DaysInMonth(cha r unsigned const month)
{
Really, lose the const, it just makes you look silly.

As does your insistence on putting the base type before the unsigned
qualifier. At least as important as portability, and more important
in many cases in the real world, is maintainability . While your code
might be perfectly valid and legal to the compiler, not one C
programmer in a 1000 writes code like that.

Your writing code contrary to the common idiom just because you like
the way it looks is nothing but a cause for confusion, causing others
to take longer to read and understand your code for inspection or
maintenance. If it survived code inspection, which I think not likely
in most quality shops, embedded or otherwise.
switch (month)
But remember, at this point, C requires that the unsigned char be
promoted to either an int or unsigned int anyway.
{
case 8:
And the type of the 8, and the rest of the constants in your cases
already have type int.
case 3:
case 5:
case 10: return 30;

case 1: return 28;

default: return 31;
}
}

I'd like now to bring up the topic of portable programming. In my own
code, I've begun to use types such as:

uint_fast8_t
Does that mean that you don't use 'char', 'int', 'long', etc.?
Basically I'm saying "I want the fastest integer type whose range is
at least up to 255".
Basically, you are fooling yourself if you are feeding this code to a
conforming C compiler, because it must perform the standard
promotions. If you are operating something that is not quite a
conforming C compiler, perhaps by using certain invocation options,
that's a different story, but also rather off-topic here.
In this way, I can write code that will peform optimally on both
embedded systems and PC's.
Again, if the compiler you feed this to is instructed to compile in
conforming mode, this code will be basically the same as the original
version.
To people out there who are enthusiastic about writing portable code,
do you think it's time we started using types like uint_fast8_t
instead of "unsigned int"?
Actually, I haven't had a use for the fast types yet. I have used the
(u)int_leastx_t types, for portability between DSPs where CHAR_BIT is
larger than 8, and "ordinary" platforms where CHAR_BIT is exactly 8.
In fact I've successfully written code that had to pack and unpack
binary communications packets using unit_least8_t that compiles
unchanged on CHAR_BIT 8 and CHAR_BIT 16 implementations .
Of course, even if our target platform doesn't supply an stdint.h, we
can always have a default version of it, e.g.:

typedef char unsigned uint_fast8_t;
or:
typedef unsigned uint_fast8_t;
There have been plenty of examples on the web of stdint.h files for
compilers that do not supply them. At least one was written by a
member of the C standard committee. I've written quite a few myself
for older embedded compilers. And I've written one for Visual C++ 6,
which I often use for testing algorithms.

The real issue here is premature micro optimization. The majority of
the posters and readers in this group, as opposed to
comp.arch.embed ded, are not embedded system programmers. They have,
and probably will never have, a need to port their code to anything
smaller than a 32-bit processor. Your advice is not relevant to them.

In my opinion, you are worrying about efficiency under the guise of
portability. If you are really concerned with portability, understand
that portability to other programmers is as important as portability
to other implementations and platforms.

Get rid of "char unsigned const" and write "const unsigned char" like
all the other C programmers do. Save your creativity for clever
algorithms, and write the simplest and clearest code to implement the
algorithm correctly.

And at the very end, when your program works and meets all of its
requirements, then you can look at optimizations like this. But only
if this is the code causing one of the bottle necks.

For example, if this code is executed once per day when the clock
rolls over from 23:59:50 to 0:00:00, to decide whether to change the
month and date, or just the date, on a display, what have you gained
by saving 5 or 50 clock cycles out every 24 hours?

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.l earn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
Jun 27 '08 #3
Jack Klein wrote:
On Fri, 2 May 2008 13:42:23 -0700 (PDT), Tomás Ó hÉilidhe
<to*@lavabit.co mwrote in comp.lang.c:
>Let's say we had a simple function for returning the amount of days in
a month:

unsigned DaysInMonth(uns igned const month)
{
switch (month)
{
case 8:
case 3:
case 5:
case 10: return 30;

case 1: return 28;

default: return 31;
}
}
....
>In my little code snippet above, the biggest number used is 31, which
of course would fit inside an "unsigned char".

Which would, in C, immediately be promoted to either signed or
unsigned int. So you'd gain nothing. Some, perhaps many, embedded
compilers for 8-bit micros have an option for telling the compiler not
to promote 8-bit values. Once you do that, it's not really C anymore.
For parameters and return values if they are declared as 8-bit types, you
will save instructions on an 8-bit processor. Promotion doesn't happen on
those.
> switch (month)

But remember, at this point, C requires that the unsigned char be
promoted to either an int or unsigned int anyway.
Yes, month is promoted to an int, but my compiler is clever -- it knows
that the operand is 8 bits and doesn't needlessly generate a leading zero
byte before performing the switch evaluation.

Good compilers do that kind of optimization. a = b + 5; can be done with
single byte operations for single byte operands. So can many other
expressions.
>
> {
case 8:

And the type of the 8, and the rest of the constants in your cases
already have type int.
So what? These are constants. The clever compiler knows that the 8-bit
unsigned value can be contained in a single byte.

>I'd like now to bring up the topic of portable programming. In my own
code, I've begun to use types such as:

uint_fast8_t

Does that mean that you don't use 'char', 'int', 'long', etc.?
>Basically I'm saying "I want the fastest integer type whose range is
at least up to 255".

Basically, you are fooling yourself if you are feeding this code to a
conforming C compiler, because it must perform the standard
promotions. If you are operating something that is not quite a
conforming C compiler, perhaps by using certain invocation options,
that's a different story, but also rather off-topic here.
I disagree. I am familiar with my compiler. It does take advantage of
smaller operand size. Any yes, it is conforming in regards to integer
promotion.
>In this way, I can write code that will peform optimally on both
embedded systems and PC's.

Again, if the compiler you feed this to is instructed to compile in
conforming mode, this code will be basically the same as the original
version.
Not the one I use.

--
Thad
Jun 27 '08 #4
On May 3, 4:53*am, Jack Klein <jackkl...@spam cop.netwrote:
unsigned DaysInMonth(uns igned const month)

First, omitting the "int", even if legal, is sloppy and would not
survive a code inspection in a professional organization.

I don't know whether that's a good sign or a bad sign, especially
considering I'd aspire to be better than any "profession al"
programmer.

Second, applying a const qualifier to a value parameter might pass a
code inspection, but is considered by many to be just plain prissy.

Who's talking about code inspections? I write code for myself. I write
it clear, efficient and proper. I used const wherever possible unless
it's redundant.

Which would, in C, immediately be promoted to either signed or
unsigned int. *So you'd gain nothing. *Some, perhaps many, embedded
compilers for 8-bit micros have an option for telling the compiler not
to promote 8-bit values. *Once you do that, it's not really C anymore.

Don't forget about the "as if" rule. I compiler doesn't have to do
something, it just has to act as if it does seomthing.

If you do:

char unsigned a = 5, b = 6;

char unsigned c = a + b;

Compile it and check the assembler. You'll see that only 8-Bit
registers are used.

In C, the plain "int" type is described as the "natural" type for the
system. I think a lot of people agree that this is the type you use
when you "just want to store a number", and I think a lot of people
expect it to be the fastest integer type.

You seem to be a beginning embedded programmer, particularly based on
some of the posts you've made on comp.arch.embed ded. *On the other
hand, you make these opinionated statements like "a lot of people
expect". *Who are these people? *How do you know what they expect?

Firstly, yes I'm new to embedded systems, but I consider myself to be
an experienced programmer. I've been programming in C and C++ for
about 6 or 7 years now and I have for a long time considered "int" to
be the "fast type".

I think that no experienced embedded programmer would expect that.

I realise that, and this is why they're distinct from more generic
programmers. (By generic programmers, I mean someone who writes an
algorithm and doesn't know what their platform is.)

*
I think anyone who hasn't learned not to expect that does not have the
experience to professionally program embedded systems.

Obviously, since I wrote the original post in this thread, I realise
that "int" is slow on an 8-Bit micrcontroller.

I'm talking about more generic programming, e.g. just being a C
programmer. A good C programmer should be able to write portable code
that will perform well on everything. Since the portable programmer
will assume that "int" is the best type for the job, this will have
negative consequences when the code is brought to an embedded system.

The solution: Use things like uint_fast8_t instead of int.

Most C programmers these days are woefully ignorant, and they expect
many things, such as...

--a char is signed and has a range of [-128,127]

--an int is four bytes

--a pointer is four bytes

--a float is four bytes

--there is a stack

...an I could go on and on.

Yes, the majority of programmers are bad programmers. Kind of like ice
skaters.

Any half-decent C programmer will know what freedom and restrictions
the Standard provides.

The only problem with int, however, is that it must be at least 16-
Bit.

Actually, that's not a problem. *That's a guarantee and a good one.

Are you paying attention? It's bad for 8-Bit microcontroller s. It's
fine for 16-Bit microcontroller s and upwards.

On an 8-Bit microcontroller such as the PIC16F684, this of course
means that int will NOT be the most efficient type. The problem with

Actually, it generally is the most efficient type if you need a type
that can hold an object in either of the ranges [-32767,32767] or
[0,65535].

I'm now talking about that specific range, I'm talking about storing
"just a number", even like small numbers that don't go above 200.

this however is that we have code snippets like the one above that
think they're using the best integer types for the job. If we were to

Your assumption is that they think that. *Have you asked "they" what
they think, or are you just assuming?

I've had many discussions about portability on various different
newsgroups. Do a google search of comp.lang.c for my name and
"portable portability". I never shut up about it.

Actually, speaking for more than 25 years of embedded system
development, I'd say they would most likely not rewrite the code,
Knuth being absolutely correct about premature optimization. *Once the
program was finished and meeting its requirements, but needed a
performance boost, then it might possible be rewritten as you suggest
below. *But only after a profiler or other hard measurement tool
proved that it was a bottleneck.

You'd have to have the intelligence of a squid not to realise that the
micrcontroller can work with 8-Bit numbers with a single instruction,
and that it needs mutliple instructions (and multiple bytes in memory)
to work with 16-Bit numbers.

char unsigned DaysInMonth(cha r unsigned const month)
{

Really, lose the const, it just makes you look silly.

I'm beginning to think that I should probably be glad if you think I'm
silly.

That const serves a purpose; I put it there for a reason.

As does your insistence on putting the base type before the unsigned
qualifier. *At least as important as portability, and more important
in many cases in the real world, is maintainability . *While your code
might be perfectly valid and legal to the compiler, not one C
programmer in a 1000 writes code like that.

Oh the woes of being a good programmer.

Your writing code contrary to the common idiom just because you like
the way it looks is nothing but a cause for confusion, causing others
to take longer to read and understand your code for inspection or
maintenance. *If it survived code inspection, which I think not likely
in most quality shops, embedded or otherwise.

I'm not a professional programmer. If I was, I'd make sure I'm working
with good, competant programmers. If my colleague can't get his head
around "short unsigned" then we'd be better off not working together.
I'm not prejudiced against stupid people, I just don't like working
with them.

* * switch (month)

But remember, at this point, C requires that the unsigned char be
promoted to either an int or unsigned int anyway.

Again, the assembler produced will work with a single 8-Bit register.

* * {
* * case 8:

And the type of the 8, and the rest of the constants in your cases
already have type int.

Single 8-Bit register again.

In my own
code, I've begun to use types such as:
* * uint_fast8_t

Does that mean that you don't use 'char', 'int', 'long', etc.?

Not entirely.

Basically I'm saying "I want the fastest integer type whose range is
at least up to 255".

Basically, you are fooling yourself if you are feeding this code to a
conforming C compiler, because it must perform the standard
promotions.

Against your argument is invalid. The compiler knows when the
promotion will have no effect.

>*If you are operating something that is not quite a
conforming C compiler, perhaps by using certain invocation options,
that's a different story, but also rather off-topic here.

You'll find that these smart compilers conform to the standard in
terms of integer promotion.

In this way, I can write code that will peform optimally on both
embedded systems and PC's.

Again, if the compiler you feed this to is instructed to compile in
conforming mode, this code will be basically the same as the original
version.

Again, a single 8-Bit register.

The real issue here is premature micro optimization. *The majority of
the posters and readers in this group, as opposed to
comp.arch.embed ded, are not embedded system programmers.

White coats not mixing with blue blazers?

A programmer is a programmer. I programmed in C on PC's for years
before I started doing embedded systems programming... and guess what
there was no difference.

If you have a fully-portable algorithm in compliance to the C89
standard, then it should run on everything from your microwave's
interface to your PC. The only problem with algorithm is that it might
be inefficient on the microwave if it's using "int" as its everyday
integer type. If the algorithm instead used uint_fast8_t, then the
code would be fast on every kind of system.

>*They have,
and probably will never have, a need to port their code to anything
smaller than a 32-bit processor. *Your advice is not relevant to them.

Where are you getting this distinction between a C programmer and an
embedded systems programmer. You can program an embedded system in C,
and I do it.

In my opinion, you are worrying about efficiency under the guise of
portability. *If you are really concerned with portability, understand
that portability to other programmers is as important as portability
to other implementations and platforms.

Get rid of "char unsigned const" and write "const unsigned char" like
all the other C programmers do.

Again, I've not interest to accomodate lact-lustre programmers. If
they can't get their head around a simple re-ordering of words, then
they haven't a snowball's chance in hell of understanding my more
complex algorithms.

>*Save your creativity for clever
algorithms, and write the simplest and clearest code to implement the
algorithm correctly.

And would you believe that I think my own code is simple and clear.

And at the very end, when your program works and meets all of its
requirements, then you can look at optimizations like this. *But only
if this is the code causing one of the bottle necks.

For example, if this code is executed once per day when the clock
rolls over from 23:59:50 to 0:00:00, to decide whether to change the
month and date, or just the date, on a display, what have you gained
by saving 5 or 50 clock cycles out every 24 hours?
What if the code is run in an eternal loop on a microcontroller that's
running at 4 MHz. If the microcontroller is also flashing an LED
display, then the decrease in speed will result in display flicker.
And I *have* seen this in my very own college project this year.
Jun 27 '08 #5
On Sat, 3 May 2008 04:53:12 -0700 (PDT), Tomás Ó hÉilidhe
<to*@lavabit.co mwrote in comp.lang.c:
On May 3, 4:53*am, Jack Klein <jackkl...@spam cop.netwrote:
unsigned DaysInMonth(uns igned const month)
First, omitting the "int", even if legal, is sloppy and would not
survive a code inspection in a professional organization.


I don't know whether that's a good sign or a bad sign, especially
considering I'd aspire to be better than any "profession al"
programmer.
Oh, my, I had no idea that you were the ultimate programmer, better
than all the rest, better than the best. I'll make a note of that.
Second, applying a const qualifier to a value parameter might pass a
code inspection, but is considered by many to be just plain prissy.

Who's talking about code inspections? I write code for myself. I write
it clear, efficient and proper. I used const wherever possible unless
it's redundant.
In that case, why are you bothering to waste your time bestowing your
wisdom on other, lesser, programmers? Our opinion is meaningless to
you.
Which would, in C, immediately be promoted to either signed or
unsigned int. *So you'd gain nothing. *Some, perhaps many, embedded
compilers for 8-bit micros have an option for telling the compiler not
to promote 8-bit values. *Once you do that, it's not really C anymore.


Don't forget about the "as if" rule. I compiler doesn't have to do
something, it just has to act as if it does seomthing.

If you do:

char unsigned a = 5, b = 6;

char unsigned c = a + b;

Compile it and check the assembler. You'll see that only 8-Bit
registers are used.
Sadly, I have to disagree with you there. Take ARM for example, in
the majority of the world's cell phones. I guarantee you it will use
a 32-bit register. Regardless of any compiler, past, present, or
future, regardless of options used when invoking the compiler.
In C, the plain "int" type is described as the "natural" type for the
system. I think a lot of people agree that this is the type you use
when you "just want to store a number", and I think a lot of people
expect it to be the fastest integer type.
You seem to be a beginning embedded programmer, particularly based on
some of the posts you've made on comp.arch.embed ded. *On the other
hand, you make these opinionated statements like "a lot of people
expect". *Who are these people? *How do you know what they expect?


Firstly, yes I'm new to embedded systems, but I consider myself to be
an experienced programmer. I've been programming in C and C++ for
about 6 or 7 years now and I have for a long time considered "int" to
be the "fast type".
That is one of the many assumptions you will need to rid yourself of
if you expect to become an expert embedded programmer.
I think that no experienced embedded programmer would expect that.


I realise that, and this is why they're distinct from more generic
programmers. (By generic programmers, I mean someone who writes an
algorithm and doesn't know what their platform is.)

*
I think anyone who hasn't learned not to expect that does not have the
experience to professionally program embedded systems.


Obviously, since I wrote the original post in this thread, I realise
that "int" is slow on an 8-Bit micrcontroller.

I'm talking about more generic programming, e.g. just being a C
programmer. A good C programmer should be able to write portable code
that will perform well on everything. Since the portable programmer
will assume that "int" is the best type for the job, this will have
negative consequences when the code is brought to an embedded system.
Actually, I couldn't disagree more. Most professional programmers are
concerned, as they should be, with producing error free (or as error
free as possible) programs that meet their requirements. Suggesting
that programmers for desk top environments such as *nix or Windows
should worry about their code being ported to an eight-bit micro is
inefficient and not cost effective.
The solution: Use things like uint_fast8_t instead of int.

Most C programmers these days are woefully ignorant, and they expect
many things, such as...

--a char is signed and has a range of [-128,127]

--an int is four bytes

--a pointer is four bytes

--a float is four bytes

--there is a stack

...an I could go on and on.


Yes, the majority of programmers are bad programmers. Kind of like ice
skaters.

Any half-decent C programmer will know what freedom and restrictions
the Standard provides.

The only problem with int, however, is that it must be at least 16-
Bit.
Actually, that's not a problem. *That's a guarantee and a good one.


Are you paying attention? It's bad for 8-Bit microcontroller s. It's
fine for 16-Bit microcontroller s and upwards.
My attention skills are quite adequate, thank you. You said, and
quite specifically, "The only problem with int, however, is that is
must be at least 16-Bit(sic)." In fact, it's still just a few lines
above where I am typing this, quoted several times from your original
post.

And that is absolutely, positively, not a problem, but an extremely
useful guarantee provided by the C language.

The problem you are expressing is that you think that an int is not
the most efficient type for you to use in one particular code snippet,
on one particular hardware architecture, with one particular compiler.

That is a problem with your expectations or wants, not a problem with
the C language requirement for the type int.
On an 8-Bit microcontroller such as the PIC16F684, this of course
means that int will NOT be the most efficient type. The problem with
Actually, it generally is the most efficient type if you need a type
that can hold an object in either of the ranges [-32767,32767] or
[0,65535].


I'm now talking about that specific range, I'm talking about storing
"just a number", even like small numbers that don't go above 200.

this however is that we have code snippets like the one above that
think they're using the best integer types for the job. If we were to
Your assumption is that they think that. *Have you asked "they" what
they think, or are you just assuming?


I've had many discussions about portability on various different
newsgroups. Do a google search of comp.lang.c for my name and
"portable portability". I never shut up about it.

Actually, speaking for more than 25 years of embedded system
development, I'd say they would most likely not rewrite the code,
Knuth being absolutely correct about premature optimization. *Once the
program was finished and meeting its requirements, but needed a
performance boost, then it might possible be rewritten as you suggest
below. *But only after a profiler or other hard measurement tool
proved that it was a bottleneck.


You'd have to have the intelligence of a squid not to realise that the
Oops, now your getting insulting. I don't recall casting any
aspersions on your intelligence.
micrcontroller can work with 8-Bit numbers with a single instruction,
and that it needs mutliple instructions (and multiple bytes in memory)
to work with 16-Bit numbers.
I was making a living designing, building, and selling embedded
systems with various 8-bit microprocessors and microcontroller s for at
least ten years before Microchip released the first PIC. There is
little you can teach me about 8-bit architectures.
char unsigned DaysInMonth(cha r unsigned const month)
{
Really, lose the const, it just makes you look silly.


I'm beginning to think that I should probably be glad if you think I'm
silly.

That const serves a purpose; I put it there for a reason.

As does your insistence on putting the base type before the unsigned
qualifier. *At least as important as portability, and more important
in many cases in the real world, is maintainability . *While your code
might be perfectly valid and legal to the compiler, not one C
programmer in a 1000 writes code like that.


Oh the woes of being a good programmer.
Oh, woe is you! Or should that be "are you"? Now you have ventured
into a completely subjective area, your definition of "good".

Indulge me, tell me how your insistence on writing "char unsigned
const" "good", as opposed to "const unsigned char", which is what the
vast majority of C programmers would write.

What makes that "good", and, by definition, the way (almost) everybody
else would write it not "good", or at least not as "good" as your way?
Your writing code contrary to the common idiom just because you like
the way it looks is nothing but a cause for confusion, causing others
to take longer to read and understand your code for inspection or
maintenance. *If it survived code inspection, which I think not likely
in most quality shops, embedded or otherwise.


I'm not a professional programmer. If I was, I'd make sure I'm working
with good, competant programmers. If my colleague can't get his head
around "short unsigned" then we'd be better off not working together.
I'm not prejudiced against stupid people, I just don't like working
with them.
Oh, now anyone who writes "const unsigned char" is "stupid", unless
they cheerfully adapt to your idiosyncrasies?

You can actually make a point about putting the const keyword after
the type. The C grammar basically wants it there, and only allows it
at the beginning of a declaration as a special case.

It would be quite a bit harder to provide a justification for "char
unsigned" or "long unsigned", since an unsigned char is neither an
unsigned nor a char, it is a unique type on it's own. The unsigned
keyword is not a cv qualifier, it is an integral part of the type
name.
* * switch (month)
But remember, at this point, C requires that the unsigned char be
promoted to either an int or unsigned int anyway.


Again, the assembler produced will work with a single 8-Bit register.
The assembler produced by one particular compiler.
* * {
* * case 8:
And the type of the 8, and the rest of the constants in your cases
already have type int.


Single 8-Bit register again.

In my own
code, I've begun to use types such as:
* * uint_fast8_t
Does that mean that you don't use 'char', 'int', 'long', etc.?


Not entirely.
Haven't yet attained perfection.
Basically I'm saying "I want the fastest integer type whose range is
at least up to 255".
Basically, you are fooling yourself if you are feeding this code to a
conforming C compiler, because it must perform the standard
promotions.


Against your argument is invalid. The compiler knows when the
promotion will have no effect.

*If you are operating something that is not quite a
conforming C compiler, perhaps by using certain invocation options,
that's a different story, but also rather off-topic here.


You'll find that these smart compilers conform to the standard in
terms of integer promotion.

In this way, I can write code that will peform optimally on both
embedded systems and PC's.
Again, if the compiler you feed this to is instructed to compile in
conforming mode, this code will be basically the same as the original
version.


Again, a single 8-Bit register.

The real issue here is premature micro optimization. *The majority of
the posters and readers in this group, as opposed to
comp.arch.embed ded, are not embedded system programmers.


White coats not mixing with blue blazers?

A programmer is a programmer. I programmed in C on PC's for years
before I started doing embedded systems programming... and guess what
there was no difference.
Actually, you are quite wrong about that. Does your PIC compiler
provide a double that meets the C specifications?
If you have a fully-portable algorithm in compliance to the C89
standard, then it should run on everything from your microwave's
interface to your PC. The only problem with algorithm is that it might
be inefficient on the microwave if it's using "int" as its everyday
integer type. If the algorithm instead used uint_fast8_t, then the
code would be fast on every kind of system.

*They have,
and probably will never have, a need to port their code to anything
smaller than a 32-bit processor. *Your advice is not relevant to them.


Where are you getting this distinction between a C programmer and an
embedded systems programmer. You can program an embedded system in C,
and I do it.
Because embedded programmers in C might need to worry about choosing
the best data type on some micros and DSPs, and C programmers working
in 32-bit or larger hosted environments do not.
In my opinion, you are worrying about efficiency under the guise of
portability. *If you are really concerned with portability, understand
that portability to other programmers is as important as portability
to other implementations and platforms.

Get rid of "char unsigned const" and write "const unsigned char" like
all the other C programmers do.


Again, I've not interest to accomodate lact-lustre programmers. If
"Accomodate(sic )". So everybody else who has been writing C for forty
years should accommodate you. Including Brian Kernighan and Dennis
Ritchie, including the authors of the various versions of ANSI and ISO
C standards. Obviously lack-luster programmers, the lot of them.
they can't get their head around a simple re-ordering of words, then
they haven't a snowball's chance in hell of understanding my more
complex algorithms.
You're absolutely right, I'm sure that none of people I alluded to
above could understand your clever algorithms.
*Save your creativity for clever
algorithms, and write the simplest and clearest code to implement the
algorithm correctly.


And would you believe that I think my own code is simple and clear.
But you persist in posting your code to a public forum read almost
exclusively by C programmers who conclusively demonstrate that they
don't think your way of writing code is appropriate by not writing
code the way that you do.
And at the very end, when your program works and meets all of its
requirements, then you can look at optimizations like this. *But only
if this is the code causing one of the bottle necks.

For example, if this code is executed once per day when the clock
rolls over from 23:59:50 to 0:00:00, to decide whether to change the
month and date, or just the date, on a display, what have you gained
by saving 5 or 50 clock cycles out every 24 hours?

What if the code is run in an eternal loop on a microcontroller that's
running at 4 MHz. If the microcontroller is also flashing an LED
display, then the decrease in speed will result in display flicker.
And I *have* seen this in my very own college project this year.
I will repeat, since you seem to have missed it, this paragraph of my
response:

"And at the very end, when your program works and meets all of its
requirements, then you can look at optimizations like this. *But only
if this is the code causing one of the bottle necks."

So you have correctly discovered that there were performance issues in
your program, and found optimizations that improved them. Excellent.

As I've said to you in at least one previous post, it is important for
embedded programmers working on "unusual" architectures to be aware
not only of the features and limitations of the underlying hardware,
but also of the details of their compiler.

Where you take the great and unjustified, in my opinion, leap, is in
deciding that you have uncovered a great truth and every C programmer
working on any kind of code anywhere should analyze every integer
object used in their code and use the stdint.h code for the fastest
possible type.

Quite frankly, for many programmers, that would be an absolutely
unjustified use of time and resources. They would expend extra
effort, and therefore produce working, tested code more slowly, on an
activity that would not improve the correctness or efficiency of their
code by even the tiniest amount.

Perhaps you should conduct a survey, to determine the percentage of C
programmers who are currently coding for Windows or Linux or OSX and
are planning a future port to PIC or 8051 or AVR.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.l earn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
Jun 27 '08 #6
On Sat, 03 May 2008 04:53:12 -0700, Tomás Ó hÉilidhe wrote:
On May 3, 4:53*am, Jack Klein <jackkl...@spam cop.netwrote:
unsigned DaysInMonth(uns igned const month)
(...)
>Second, applying a const qualifier to a value parameter might pass a
code inspection, but is considered by many to be just plain prissy.


Who's talking about code inspections? I write code for myself. I write
it clear, efficient and proper. I used const wherever possible unless
it's redundant.
(...)
>
char unsigned DaysInMonth(cha r unsigned const month)
{

Really, lose the const, it just makes you look silly.


I'm beginning to think that I should probably be glad if you think I'm
silly.

That const serves a purpose; I put it there for a reason.

Am guessing your reason is to tell yourself as the function's
/implementer/ that you are not going to modify the function
argument. However, most functions are written for the caller.

As a programmer who is going to call your function, if I were to
look at your function declaration, I see that it has a value
parameter (i.e., a copy of my argument is passed to your function).
So, the const there is indeed redundant to the caller.
--
ROT-13 email address to reply
Jun 27 '08 #7
Tomás Ó hÉilidhe wrote:
On May 3, 4:53 am, Jack Klein <jackkl...@spam cop.netwrote:
>Get rid of "char unsigned const" and write "const unsigned char" like
all the other C programmers do.


Again, I've not interest to accomodate lact-lustre programmers. If
they can't get their head around a simple re-ordering of words, then
they haven't a snowball's chance in hell of understanding my more
complex algorithms.
Are we witnessing the return of Frederick Gotham?

--
Ian Collins.
Jun 27 '08 #8
On May 4, 8:09*am, Ian Collins <ian-n...@hotmail.co mwrote:
Are we witnessing the return of Frederick Gotham?

I am not sock puppeting. The most recent post I can find of Frederick
Gotham dates back to Dec 4th 2006, and quite ironically the first
thing Google found when I did a search was a thread in which he was
accused of sock puppeting; less ironically, you yourself made quite a
contribution to that thread.

I have my real e-mail address attached to my posts and I only post
under one name (on all kinds of fora across the internet), so I'd
appreciate if you'd abandon that accusation.
Jun 27 '08 #9
Tomás Ó hÉilidhe wrote:
>
.... snip ...
>
I have my real e-mail address attached to my posts and I only post
under one name (on all kinds of fora across the internet), so I'd
appreciate if you'd abandon that accusation.
That is not a good idea, because of the ease with which the
spammers can access it. I suggest putting the real address in the
'Reply-To' header, which is much less accessible, but is
automatically used for email replies. My from address is also
real, but does nothing but collect spam.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home .att.net>
Try the download section.
** Posted from http://www.teranews.com **
Jun 27 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
13018
by: David Fisher | last post by:
The most common sizes of integer types seem to be: 8 bits - signed char 16 bits - short 16 or 32 bits - int 32 or 64 bits - long Question #1: Does anyone know how common sizes other than these are ? I know that the
13
3673
by: Shailesh Humbad | last post by:
I wrote a short page as a quick reference to c++ integer data types. Any feedback welcome: http://www.somacon.com/blog/page11.php
20
9133
by: GS | last post by:
The stdint.h header definition mentions five integer categories, 1) exact width, eg., int32_t 2) at least as wide as, eg., int_least32_t 3) as fast as possible but at least as wide as, eg., int_fast32_t 4) integer capable of holding a pointer, intptr_t 5) widest integer in the implementation, intmax_t Is there a valid motivation for having both int_least and int_fast?
5
3182
by: Vtd | last post by:
Hi All, Simple question regarding byte to integer conversion: integers are 32, char is 8 bits. unsigned int a; int b; char c; .... a = (unsigned int)c; /* c is 0 extended to integer (upper 24 bits of a filled with 0's). Correct? */
61
3332
by: John Baker | last post by:
When declaring an integer, you can specify the size by using int16, int32, or int64, with plain integer being int32. Is integer the accepted default in the programming community? If so, is there a way to remove the ones with size predefined from the autolisting of types when I am declaring something? -- To Email Me, ROT13 My Shown Email Address
21
4097
by: Frederick Gotham | last post by:
I set about trying to find a portable way to set the value of UCHAR_MAX. At first, I thought the following would work: #define UCHAR_MAX ~( (unsigned char)0 ) However, it didn't work for me. Could someone please explain to me what's going on? I would have thought that the following happens: (1) The literal, 0, whose type is int, gets converted to an unsigned char.
159
6191
by: Bob Timpkinson | last post by:
Hi, I have a 32-bit machine... Is there anyway I can get gcc to use the following integer sizes? char: 8 bits short: 16 bits int: 32 bits long: 64 bits long long: 128 bits
130
6702
by: euler70 | last post by:
char and unsigned char have specific purposes: char is useful for representing characters of the basic execution character set and unsigned char is useful for representing the values of individual bytes. The remainder of the standard integer types are general purpose. Their only requirement is to satisfy a minimum range of values, and also int "has the natural size suggested by the architecture of the execution environment". What are the...
30
31791
by: DanielJohnson | last post by:
I have seen many legacy code use uint8_t or uint16_t to override the default compiler setting of an integer's length. I am using gcc on Linux and a sizeof(int) gives me 4. I want the ability to define an 8, 16 or 32 bit integer. I tried using uint8_t but the gcc doesn't like it. Do I need to modify any setting or declare typdefes. Please guide me. Your answer is greatly appreciated.
0
7931
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8233
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8224
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6637
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5399
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
3849
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
2374
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1461
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
1198
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.