Re: size_t best practice

Liste des GroupesRevenir à l c 
Sujet : Re: size_t best practice
De : andreytarasevich (at) *nospam* hotmail.com (Andrey Tarasevich)
Groupes : comp.lang.c
Date : 20. Aug 2024, 15:53:54
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <va275j$3d6tp$1@dont-email.me>
References : 1
User-Agent : Mozilla Thunderbird
On 08/18/24 1:03 AM, Mark Summerfield wrote:
 However, this means I have to be very careful never to decrement a size_t of
value 0, since, e.g., size_t size = 0; size--; results in size ==
18446744073709551615.
That's a completely incorrect conclusion. There's nothing wrong with decrementing a 0 of type `size_t`. It results in perfectly defined behavior. It produces a `(size_t) -1` value.
For example, iteration all the way to 0 can be idiomatically implemented as
   for (some_unsigned_type i = size; (some_unsigned_type) i != -1; --i)
     ...
This will work, even though it will eventually decrement a zero value.
If you are sure that the type is "large" (e.g. `int` or larger), then the cast is unnecessary
   for (some_unsigned_type i = size; i != -1; --i)
     ...
(Note, BTW, that it also works perfectly for signed index types.)

So I need to guard against this. Here is an example I'm using
(without the assert()s):
 void vec_insert(vec* v, size_t index, void* value) {
     if (v->_size == v->_cap) {
         vec_grow(v);
     }
     for (size_t i = v->_size - 1; i >= index; --i) {
         v->_values[i + 1] = v->_values[i];
         if (!i) // if i == 0, --i will wrap!
             break;
     }
     v->_values[index] = value;
     v->_size++;
}
No, that's rather weird and unnecessarily overwrought way to guard against this.
We can immediately apply the pattern I demonstrated above to this and get
   for (size_t i = v->_size - 1; i != index - 1; --i)
     v->_values[i + 1] = v->_values[i];
Done. No need for an extra safeguard.
Another widely used idiom for this kind of iteration is
   for (size_t i = v->size; i-- > index;)
     v->_values[i + 1] = v->_values[i];
That's all. No need for any additional safeguards.

So is it considered best practice to use int, long, long long, or size_t,
in situations like these?
It is not clear what you mean here. Use signed types everywhere, including container sizes? Or use signed types just for iteration?
Anyway, the former is an iffy practice intended to replace learning with a safety blanket. The latter just leads to an unnecessary salad of types.
--
Best regards,
Andrey

Date Sujet#  Auteur
18 Aug 24 * size_t best practice23Mark Summerfield
18 Aug 24 +* Re: size_t best practice3Ike Naar
18 Aug 24 i`* Re: size_t best practice2Mark Summerfield
20 Aug 24 i `- Re: size_t best practice1Andrey Tarasevich
18 Aug 24 +- Re: size_t best practice1Michael S
18 Aug 24 +- Re: size_t best practice1Tim Rentsch
18 Aug 24 +* Re: size_t best practice6Stefan Ram
18 Aug 24 i+* Re: size_t best practice4Michael S
19 Aug 24 ii`* Re: size_t best practice3Tim Rentsch
19 Aug 24 ii `* Re: size_t best practice2Michael S
19 Aug 24 ii  `- Re: size_t best practice1Tim Rentsch
18 Aug 24 i`- Re: size_t best practice1Tim Rentsch
20 Aug 24 +* Re: size_t best practice7Andrey Tarasevich
20 Aug 24 i+* Re: size_t best practice3Andrey Tarasevich
20 Aug 24 ii`* Re: size_t best practice2Andrey Tarasevich
22 Aug 24 ii `- Re: size_t best practice1Tim Rentsch
22 Aug 24 i`* Re: size_t best practice3Tim Rentsch
22 Aug 24 i `* Re: size_t best practice2Ike Naar
22 Aug 24 i  `- Re: size_t best practice1Tim Rentsch
24 Aug 24 +* Re: size_t best practice3Bonita Montero
25 Aug 24 i`* Re: size_t best practice2Bonita Montero
26 Aug 24 i `- Re: size_t best practice1Vir Campestris
27 Aug 24 `- Re: size_t best practice1Bonita Montero

Haut de la page

Les messages affichés proviennent d'usenet.

NewsPortal