更改c函数参数中错误检查的类型?

更改c函数参数中错误检查的类型?,c,types,error-handling,C,Types,Error Handling,我一直在尝试处理我正在编写的一个简单c库中的错误。检查参数错误(或打字错误)的最佳实践是什么?假设我有这样一个函数: intfoo(size\t maxSize);//(返回的int是错误类型) 然后让我们假设foo继续创建maxSize元素的数组。我的问题是:如果有人错误地使用带有负数的foo,那么这个数字将被解释为size\u t,并且可能在没有警告的情况下变得非常大: printf(“zu”,-10);//4294967286在我的机器上 程序编译时没有错误或警告,foo试图创建一个巨大的

我一直在尝试处理我正在编写的一个简单c库中的错误。检查参数错误(或打字错误)的最佳实践是什么?假设我有这样一个函数:

intfoo(size\t maxSize);//(返回的int是错误类型)

然后让我们假设
foo
继续创建
maxSize
元素的数组。我的问题是:如果有人错误地使用带有负数的
foo
,那么这个数字将被解释为
size\u t
,并且可能在没有警告的情况下变得非常大:

printf(“zu”,-10);//4294967286在我的机器上

程序编译时没有错误或警告,
foo
试图创建一个巨大的数组,程序在运行时暂停,并且无法立即找到原因(我的灵魂)

如何妥善处理?
foo
在检查是否为正后,是否应将
long
转换为
size\u t
?(然后返回相应的错误?)。或者
foo
应该保留
size\u t
而不去打扰那些不遵循
foo
签名的用户吗

编辑答案:


一致同意,保留真正的签名
int foo(size\t maxSize)
,否则会产生误导(因为
size\t
的最大值是一个有效参数)。让用户来处理,也许可以帮助他完成文档。

检查具有高位设置的参数的额外代码似乎太多了。过度使用防御性编码并不好;它使源文件膨胀,使二进制文件变慢

使用您的库的人有责任不传递伪参数,如大小为负值


确保分配失败时代码不会崩溃或泄漏内存,并在这种情况下返回错误代码。我认为这是最好的办法。如果有人以负大小调用您的函数,这是一个主要错误,干净地返回错误似乎是使他们易于调试的最佳方法。

检查具有高位设置的参数的额外代码似乎太多了。过度使用防御性编码并不好;它使源文件膨胀,使二进制文件变慢

使用您的库的人有责任不传递伪参数,如大小为负值


确保分配失败时代码不会崩溃或泄漏内存,并在这种情况下返回错误代码。我认为这是最好的办法。如果有人以负大小调用您的函数,这是一个主要错误,干净地返回错误似乎是使他们易于调试的最佳方法。

无符号整数(如
size\u t
)的下溢是例如:
UINT\u MAX
表示
无符号整数。可以这么说,它们围绕在一起,行为在标准中有定义:

否则,如果新类型是无符号的,则通过重复地将新类型中可以表示的最大值加上0减去1,直到该值在新类型的范围内,来转换该值。60)

ISO 1999:2011第6.3.1.3节

size\u t
(ISO 1999:2011 7.19中描述的
stddef.h
附录B.18)的最小尺寸为
size\u MAX
(ISO 1999:2011 7.20.3中描述的,设置在
stdint.h
附录B.19中)

其执行定义值的大小应等于或大于 (绝对值)大于下面给出的相应值,且符号相同

ISO 1999:2011 7.20.3

但从引文中可以看出,这只是最低限度。您可以通过以下方式隐式触发转换:

size_t size_t_max = (size_t) -1;
并检查
foo
的输入
maxSize
,如果其大小相同

已编辑

我不知道这是我的英语不好,还是对一个委员会制定的行业标准的基本误解,该委员会的成员来自不同的公司,他们都试图让自己对该标准感兴趣。这就是“这个和那个被定义为有那些值,但是…”形式的许多折衷的原因,然后是一系列例外,或者,在一种编程语言的标准的情况下,它可以非常接近于硬件,比如C,定义一个最小值,剩下的被分配给“单独的实现”

没有多少人对此有问题(除了那些不得不为该语言构建编译器的穷人;-)),这是你从一个委员会得到的,这是预期的结果:只有最低的公分母被固定下来,其余的是“实现定义的”。在苍白的危险面前重复我自己:这没有问题

这导致了许多变通方法和其他怪癖,就像这里的这个问题一样

size\t
的数据类型必须是无符号的,并且能够容纳至少2^16的数字(为简单起见,从这里开始称为“size”)。仅此而已。如果需要,用于
size\u t
的数据类型可能比
size\u MAX
保存的数据更多

C标准不仅仅是为x86erCPU编写的,它还有更多的用途,尤其是现在可以买到的数百种小型嵌入式处理器。其中许多具有不同于32或64的整数位长度。例如,有些也有24位大整数。对于如此大量大小不同的整数,LibC for it的写操作可以非常自由地选择他们想要的,例如a
size\u t
。他们还可以选择您想要的
SIZE\u MAX
值,例如:您可以为该处理器提供的最小内存量

这意味着关于
size\u t
size\u MAX
之间的连接,您可以假定的唯一一件事是用于
size\t的整数类型的大小<