Andy Alt
Andy Alt

Reputation: 426

Is using type unsigned char acceptable when only a small number is needed?

If writing a program, and I need a number that is lower than 255, is it ok to use type unsigned char for use as a number, such as if I need a number to make a loop? Is there any reason, including sticking to tradition and convention, to stick to declaring numbers with int and float, etc.

For example, should code like this never be used? Or would it be good practice to use an unsigned char in this case, since it allocates less memory than a short int?

#include <stdio.h>

typedef unsigned char short_loop;

int main(int argc, char *argv[])
{
  short_loop i;

  for(i = 0; i < 138; i++)
      printf("StackOverflow Example Code\n");

  return 0;
}

I'm asking for future reference, and only using the code above to help illustrate.

Upvotes: 0

Views: 358

Answers (3)

M.M
M.M

Reputation: 141554

Yes, using unsigned char is fine. I would not use the short_loop typedef though, it just obfuscates the code for no reason.

Some would recommend using uint8_t to emphasize that the intent is a small integer, instead of character data; even though uint8_t is very likely to be a typedef for unsigned char.

Theoretically you could use the typedef uint_fast8_t, which is supposed to mean "an unsigned integer type, at least 8 bits, and the fastest possible of the available types" , obviously the interpretation of "fastest" is a bit vague.

Upvotes: 2

Peter
Peter

Reputation: 36597

I wouldn't do it.

If your program is working with large arrays of values, then there is a benefit in terms of memory usage of using an array of char rather than an array of int.

But, for the control variable of a single loop, there is unlikely to be much benefit, and potentially a performance hit, for several reasons.

Comparing i < 138 will promote i to int before doing the comparison, since 138 is of type int. Promotions (and down-conversions) also potentially occur with initialising and incrementing i as well.

int is typically the "native type" on the host machine - which normally means it is a type that is preferred on the host (e.g. hardware provides registers that are optimised for performance when operating on that type). Which, even if some technique is used to prevent promotion of unsigned char to int before doing the comparisons in the loop, operations on int may be more effective anyway.

So, in the end, your approach might or might not give a performance benefit. The only way to be sure would be to profile the code .... and the benefits (or otherwise) would be compiler dependent (e.g. affected by optimisation approaches) and host dependent (e.g. how efficient are operations on unsigned char in comparison with operations on int)

Your approach also makes the code harder to understand, and therefore harder to get right. And, if some other programmer (or you) modify the code in future, any benefit may be negated .... for example, by accidentally reintroducing unintended type conversions.

Upvotes: 2

Imobilis
Imobilis

Reputation: 1489

For use with PC - not very good practice. For use in embedded device - depends.

If it is guaranteed that it will not exceed 255, then sure you can use it as it is converted to an int anyway, but the memory difference is not very significant in this example.

It violates readability.


And as others said you are obfuscating your code unnecessarily. With the type definition.. giving it ugly name too. indexes are known to be of type int. And that's all.

Upvotes: 1

Related Questions