如果将size_t签名为-1会发生什么

时间:2018-09-11 16:10:35

标签: c

如果size_t像-1那样签名是错误的代码?

例如,在此strncat实现中,函数size_t的末尾为-1。会溢出吗?

考虑以下示例:

#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;
}

2 个答案:

答案 0 :(得分:2)

  

如果size_t签名为-1(?),会发生什么情况

如果代码确实打印了"-1",则说明该编译不符合C。

  在此strncat实现中,函数p_t末尾的

为-1。

不,对于合格的C编译器,它不是-1。

size_t是一个宽度不小于16位的 unsigned 整数。

while (len--) {循环持续到len == 0。使用后减量len--,求值后的值将回绕到SIZE_MAX,这是一个较大的正值。

  

会溢出吗?

从数学上讲,size_t数学可能会溢出。在C中,无符号的数学定义很好,可以环绕 1 ,实际上对类型SIZE_MAX + 1的取模为size_t。 §6.2.59


我希望printf("%zu\n",len);报告184467440737095516154294967295或其他Mersenne number

  

size_t,它是sizeof运算符结果的无符号整数类型; C11dr§7.192


1 涉及无符号操作数的计算永远不会溢出,因为无法用所得的无符号整数类型表示的结果的模数要比可以表示的最大值大一个根据结果​​类型。


可疑的代码

考虑util_strncat(ptr, "", size)可能导致不确定的行为(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'!!
}

答案 1 :(得分:0)

在任何情况下,%zu都无法打印负数。当类型size_t的无符号数减小时,其值变为SIZE_MAX