theriver
theriver

Reputation: 325

What happens if size_t is signed like -1

If size_t is signed like -1 is incorrect the code?

For example in this strncat implementation at the end of function size_t is -1. Can overflow?

Consider this example:

#include <stdio.h>
#include <string.h>

char *util_strncat(char *destination, const char *source, size_t len) {
   char *temp = destination + strlen(destination);

   while (len--) {
      *temp++ = *source++;
      if(*source == '\0'){
         break;
      }
   }
   *temp = '\0';

   printf("%zu\n",len); //-1

   return destination;
}

int main() {
   char dest[7] = "abcd";
   char src[] = "efg";
   util_strncat(dest, src, 2);
   printf("%s\n", dest);

   return 0;
}

Upvotes: 1

Views: 317

Answers (2)

chux
chux

Reputation: 153547

what happens if size_t is signed like -1 (?)

If code truly printed a "-1", then the compilation is not C compliant.

in this strncat implementation at the end of function size_t is -1.

No it is not -1 with a conforming C compiler.

size_t is an unsigned integer of some width - at least 16 bits.

while (len--) { loop continues until len == 0. With the post decrement len--, the value after the evaluation wraps around to SIZE_MAX, some large positive value.

Can overflow?

Mathematically yes size_t math can overflow. In C unsigned math is well defined to wrap around1, in effect modulo SIZE_MAX + 1 for type size_t. §6.2.5 9


I'd expect printf("%zu\n",len); to report 18446744073709551615, 4294967295 or some other Mersenne number.

size_t which is the unsigned integer type of the result of the sizeof operator; C11dr §7.19 2


1 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.


Questionable code

Consider util_strncat(ptr, "", size) can lead to undefined behavior (UB).

int main() {
   char dest[7] = "abcd";
   char src[] = "\0xyz";
   util_strncat(dest, src, 2);
   printf("%s\n", dest);
   printf("%c\n", dest[5]); // 'x'!!
}

Upvotes: 2

0___________
0___________

Reputation: 67546

The %zu cant print the negative number at any circumstances. When unsigned number of the type size_t wraps over when decreasing its value becomes SIZE_MAX.

Upvotes: 0

Related Questions