【问题标题】:Real implementation where sizeof(size_t) < sizeof(unsigned int)sizeof(size_t) < sizeof(unsigned int) 的实际实现
【发布时间】:2016-08-24 12:50:14
【问题描述】:

我知道 C 标准允许实现

(sizeof(unsigned) > sizeof(size_t))

(sizeof(int) > sizeof(ptrdiff_t))

是真的。但是有没有真正的实现,其中之一是正确的?

背景

我写了一个类似于asprintf() 的函数(因为asprintf() 不可移植),而snprintf() 返回一个int 但需要一个size_t 参数,所以我应该检查是否leni(如下所示) 在这段代码中不小于SIZE_MAX

va_copy(atmp,args)
int leni = vsnprintf(NULL,0,format,atmp); //get the size of the new string
va_end(atmp);
if(leni<0)
  //do some error handling
if(leni>=SIZE_MAX) //do i need this part?
  //error handling
size_t lens = ((size_t)leni)+1;
char *newString = malloc(lens);
if(!newString)
  //do some error hanling
vsnprintf(newString,lens,format,args)!=lens-1)

【问题讨论】:

  • 我不确定这是否真的可行,否则sizeof(char[LARGE_NUMBER]) 不会总是有效。
  • @OliverCharlesworth 它并不总是有效,如果你写类似 char str[1024ULL*1024ULL*1024ULL*5];,你会在 32 位机器上得到一个编译错误(至少在我的情况下gcc -m32)(但不在 AMD64 上)
  • @OliverCharlesworth 没必要。如果括号中的常量表达式生成了一个不能用size_t表示的对象,这将是sizeof的结果,那么编译器会产生错误。
  • @2501 - 题外话:如果数组大小是通过变量传递的(即,如果它是 VLA 类型)呢?大概必须是运行时错误/UB。
  • 使用静态断言。

标签: c sizeof size-t


【解决方案1】:

虽然标准没有禁止 INT_MAX 不会小于 SIZE_MAX,但函数 vsnprintf 保证返回值不会大于 SIZE_MAX。

如果函数成功,则返回值必须小于其第二个参数1。此参数的类型为 size_t,因此返回值必须小于 SIZE_MAX.2

如果您不相信,您始终可以使用评估 INT_MAX > SIZE_MAX 的预处理器指令,然后包含检查 vsnprintf 结果所需的代码。


1 下面标准引用中提到的标识符 n,是 vsnprintf 的第二个参数。

2(引自:ISO/IEC 9899:201x 7.21.6.12 The vsnprintf function 3)
vsnprintf 函数返回将要写入的字符数 n 足够大,不包括终止的空字符或负数 发生编码错误时的值。因此,空终止输出已 当且仅当返回值是非负数且小于 n 时才完全写入。

【讨论】:

  • 对不起,如果我不能 100% 理解你。但是如果你设置n为0,(我是做什么的)返回的Number一定不能等于或小于n,那么返回的值不就大于SIZE_MAX了吗?
  • @12431234123412341234123 标准意味着返回值不能大于 n,它有 SIZE_MAX 的限制。如果您认为裁决过于模糊而不可靠,只需添加由预处理器指令保护的检查即可。
猜你喜欢
  • 2013-10-20
  • 2013-02-19
  • 1970-01-01
  • 2021-12-06
  • 2013-09-19
  • 2012-12-19
  • 2019-12-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多