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 "professional"
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.
You seem to be a beginning embedded programmer, particularly based on
some of the posts you've made on comp.arch.embedded. 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.
Actually, that's not a problem. That's a guarantee and a good one.
Are you paying attention? It's bad for 8-Bit microcontrollers. It's
fine for 16-Bit microcontrollers 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.
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.
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.
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.
And the type of the 8, and the rest of the constants in your cases
already have type int.
Single 8-Bit register again.
Does that mean that you don't use 'char', 'int', 'long', etc.?
Not entirely.
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.
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.embedded, 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.