如果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;
}
答案 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);
报告18446744073709551615
,4294967295
或其他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
。