Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The use of size_t in an array iterator

Tags:

c++

arrays

c

size-t

I have learned recently that size_t was introduced to help future-proof code against native bit count increases and increases in available memory. The specific use definition seems to be on the storing of the size of something, generally an array.

I now must wonder how far this future proofing should be taken. Surely it is pointless to have an array length defined using the future-proof and appropriately sized size_t if the very next task of iterating over the array uses say an unsigned int as the index array:

void (double* vector, size_t vectorLength) {
    for (unsigned int i = 0; i < vectorLength; i++) {
        //...
    }
}

In fact in this case I might expect the syntax strictly should up-convert the unsigned int to a size_t for the relation operator.

Does this imply the iterator variable i should simply be a size_t?

Does this imply that any integer in any program must become functionally identified as to whether it will ever be used as an array index?

Does it imply any code using logic that develops the index programmatically should then create a new result value of type size_t, particularly if the logic relies on potentially signed integer values? i.e.

double foo[100];
//...
int a = 4;
int b = -10;
int c = 50;

int index = a + b + c;
double d = foo[(size_t)index];

Surely though since my code logic creates a fixed bound, up-converting to the size_t provides no additional protection.

like image 372
J Collins Avatar asked Mar 28 '14 12:03

J Collins


1 Answers

Surely it is pointless to have an array length defined using the future-proof and appropriately sized size_t if the very next task of iterating over the array uses say an unsigned int as the index array

Yes it is. So don't do it.

In fact in this case I might expect the syntax strictly should up-convert the unsigned int to a size_t for the relation operator.

It will only be promoted in that particular < operation. The upper limit of your int variable will not be changed, so the ++ operation will always work with an int, rather than a size_t.

Does this imply the iterator variable i should simply be a size_t?

Does this imply that any integer in any program must become functionally identified as to whether it will ever be used as an array index?

Yeah well, it is better than int... But there is a smarter way to write programs: use common sense. Whenever you declare an array, you can actually stop and consider in advance how many items the array would possibly need to store. If it will never contain more than 100 items, there is absolutely no reason for you to use int nor to use size_t to index it.

In the 100 items case, simply use uint_fast8_t. Then the program is optimized for size as well as speed, and 100% portable.

Whenever declaring a variable, a good programmer will activate their brain and consider the following:

  • What is the range of the values that I will store inside this variable?
  • Do I actually need to store negative numbers in it?
  • In the case of an array, how many values will I need in the worst-case? (If unknown, do I have to use dynamic memory?)
  • Are there any compatibility issues with this variable if I decide to port this program?

As opposed to a bad programmer, who does not activate their brain but simply types int all over the place.

like image 151
Lundin Avatar answered Oct 22 '22 18:10

Lundin