Coding style: uint8_t for 256 entries

Programming, for all ages and all languages.
onlyonemac
Member
Member
Posts: 1146
Joined: Sat Mar 01, 2014 2:59 pm

Coding style: uint8_t for 256 entries

Post by onlyonemac »

Hi,

This is not so much a question of how to write code, but a matter of coding style. Say I have some code like the following:

Code: Select all

#define TABLE_ADDRESS (void*) 0x00030000
#define TABLE_SIZE 256

static void init_table()
{
	domain	(*table)[TABLE_SIZE];
	uint8_t	current_entry;

	table = TABLE_ADDRESS;

	current_entry = 0;
	while (current_entry < TABLE_SIZE)
	{
		((*table)[current_entry]).name = NULL;
		((*table)[current_entry]).format = 0;
		((*table)[current_entry]).size = 0;

		current_entry += 1;
	}
}
The relevant lines here are "#define TABLE_SIZE 256", "uint8_t current_entry;", and "while (current_entry < TABLE_SIZE)". As you can see, the loop will never end because current_entry will keep wrapping round from 0 to 255 and never reach 256.

So how should I make it so that I can count 256 values in a uint8_t? Using a uint16_t seems a bit wasteful here, but in reality I have to limit the table size to only 255 values. It really seems like I should be able to initialise an array of 256 values using a uint8_t for the counter, but I may be wrong. Am I missing something here, or do I really need to either reduce the table to 255 values or switch to a uint16_t for the counter? If so, which of the latter two would be more acceptable (considering that the size of the table is kind of flexible)?

Thanks,

onlyonemac
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
User avatar
cmpsb
Posts: 4
Joined: Sat Nov 14, 2015 3:59 am
Location: Netherlands
Contact:

Re: Coding style: uint8_t for 256 entries

Post by cmpsb »

If you insist on using uint8_t, how about

Code: Select all

   uint8_t current_entry = 0;
   do
   {
      ...

      current_entry += 1;
   } while (current_entry > 0);
?

Code: Select all

repne cmpsb
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Coding style: uint8_t for 256 entries

Post by gerryg400 »

onlyonemac wrote:Using a uint16_t seems a bit wasteful here,
You should use an int or a size_t and allow the compiler to decide the best way. There isn't any waste since current_entry is a stack variable and will be aligned as the compiler sees fit anyway.
If a trainstation is where trains stop, what is a workstation ?
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Coding style: uint8_t for 256 entries

Post by bluemoon »

onlyonemac wrote:So how should I make it so that I can count 256 values in a uint8_t? Using a uint16_t seems a bit wasteful here
No. The array index will likely to be promoted to native address size anyway.
I suggest to use native integer or size_t to give you flexibility to change the table size.
User avatar
iansjack
Member
Member
Posts: 4685
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Coding style: uint8_t for 256 entries

Post by iansjack »

Am I missing something here?

Why not use a "for" loop? (It may be no more efficient, but it is a clearer style of coding IMO.)

Edit: I should add, use a uint_16. If your C-compiler is at all recent you can declare the variable within the loop ( "for (uint_16 i = ... )" ) so it will only use the extra byte of storage whilst the loop is executing. Hardly a big deal. In any case the lifetime of the variable is likely to be fairly short so you are worrying about nothing when you say it is wasteful.
Last edited by iansjack on Fri Nov 27, 2015 3:58 pm, edited 1 time in total.
onlyonemac
Member
Member
Posts: 1146
Joined: Sat Mar 01, 2014 2:59 pm

Re: Coding style: uint8_t for 256 entries

Post by onlyonemac »

cmpsb wrote:If you insist on using uint8_t, how about

Code: Select all

   uint8_t current_entry = 0;
   do
   {
      ...

      current_entry += 1;
   } while (current_entry > 0);
?
Sounds interesting, if not a little hackish, although I'm not familiar with using do ... while loops in C so I am more likely to get "off-by-one" bugs if I use them in the few places where I need to iterate through this table.
bluemoon wrote:
onlyonemac wrote:So how should I make it so that I can count 256 values in a uint8_t? Using a uint16_t seems a bit wasteful here
No. The array index will likely to be promoted to native address size anyway.
I suggest to use native integer or size_t to give you flexibility to change the table size.
That seems like a good idea; I might do that, although the thing is that if I switch to a 32-bit index then I feel compelled to "max out" the array size and have 4294967296 entries lol. Such are the joys of Asperger's...

Anyway, I might just leave it at 255 for now. This table is really only used in one code module, and the size of the table doesn't honestly affect anything except the maximum number of items that can be handled by that module. 256 is more than enough; extending it at any time would require modification of that module only because of the abstraction between it and other modules.
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
kzinti
Member
Member
Posts: 898
Joined: Mon Feb 02, 2015 7:11 pm

Re: Coding style: uint8_t for 256 entries

Post by kzinti »

Use an int or a size_t. I prefer the former, some prefer the later.
onlyonemac
Member
Member
Posts: 1146
Joined: Sat Mar 01, 2014 2:59 pm

Re: Coding style: uint8_t for 256 entries

Post by onlyonemac »

iansjack wrote:Why not use a "for" loop? (It may be no more efficient, but it is a clearer style of coding IMO.)
That would not change anything, as the loop condition is still evaluated before execution of the loop body. The only solution that I can see that works with a uint8_t is the one suggested by cmpsb.
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
kzinti
Member
Member
Posts: 898
Joined: Mon Feb 02, 2015 7:11 pm

Re: Coding style: uint8_t for 256 entries

Post by kzinti »

Relying on the uint8_t's overflowing to 0 is non-standard / non-conforming / non-portable and will get you in trouble at some point.

Basically, underflow/overflow behaviour for integers is undefined in the C and C++ standards. The compiler can and will optimize this into an infinite loop depending on the compiler options you use.

Just use an a signed int, it's the safest thing and the most efficient as well.
User avatar
iansjack
Member
Member
Posts: 4685
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Coding style: uint8_t for 256 entries

Post by iansjack »

onlyonemac wrote:
iansjack wrote:Why not use a "for" loop? (It may be no more efficient, but it is a clearer style of coding IMO.)
That would not change anything, as the loop condition is still evaluated before execution of the loop body. The only solution that I can see that works with a uint8_t is the one suggested by cmpsb.
Yes; I clarified my post in an edit. I just think that a "for" loop is cleaner when iterating a fixed number of times.

But, in any case, as I mention in my edit, the worry about larger variables being wasteful is illusory. They are only transitory.
onlyonemac
Member
Member
Posts: 1146
Joined: Sat Mar 01, 2014 2:59 pm

Re: Coding style: uint8_t for 256 entries

Post by onlyonemac »

Yes I get it that having a larger variable is not really wasteful of space or processing power, but it still feels "wasteful" to have a whole extra 8 (or 12) bits when only one of those bits is used on and only on the very last iteration of the loop. Using a uint8_t seems "cleaner" when I am only needing a relatively small number of items, so I will just make it 255 elements instead of 256 as it doesn't *really* make a difference.
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
User avatar
iansjack
Member
Member
Posts: 4685
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Coding style: uint8_t for 256 entries

Post by iansjack »

If you only need 255 elements then a uint_8 is fine. But don't make the mistake of confusing what seems to be wasteful with what actually is. You can waste a lifetime chasing illusory "improvements" to code. Using one extra byte for a few moments is not wasteful (especially when you are initializing a 256 element array of structures each consisting of several bytes).
intx13
Member
Member
Posts: 112
Joined: Wed Sep 07, 2011 3:34 pm

Re: Coding style: uint8_t for 256 entries

Post by intx13 »

If you are interested in that level of constraint of resources (whether for fun, for OCD, or for some other reason), you probably want to use assembly anyway. Tell GCC to dump the assembly code for your program and look at it - you'll probably see more "unnecessary" uses of wide registers/aligned memory than your loop variable.
cmdrcoriander
Member
Member
Posts: 29
Joined: Tue Jan 20, 2015 8:33 pm

Re: Coding style: uint8_t for 256 entries

Post by cmdrcoriander »

onlyonemac wrote:Yes I get it that having a larger variable is not really wasteful of space or processing power, but it still feels "wasteful" to have a whole extra 8 (or 12) bits when only one of those bits is used on and only on the very last iteration of the loop. Using a uint8_t seems "cleaner" when I am only needing a relatively small number of items, so I will just make it 255 elements instead of 256 as it doesn't *really* make a difference.
If 'waste' is what you're concerned with, consider that the compiler will almost definitely be using a full word (32 or 64 bits) for that variable - it's likely to just be in a register, but even in memory, the compiler is pretty likely to make sure it's word-aligned by padding it with extra bytes. The only one being wasteful is you, by not using those bits to free yourself from trivial worries like this :D
Techel
Member
Member
Posts: 215
Joined: Fri Jan 30, 2015 4:57 pm
Location: Germany
Contact:

Re: Coding style: uint8_t for 256 entries

Post by Techel »

kiznit wrote: Basically, underflow/overflow behaviour for integers is undefined in the C and C++ standards.
Over/Underflow for unsigned integers is well defined :) :
A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.
Post Reply