函数对非法参数输入的判断需要做到什么程度?

zqy1999 2004-06-18 01:05:01
我们开发了一套API函数库,现在在进行测试,有这样一个函数,完成对一个或多个SConfig结构对象(SConfig是我们定义的一个结构类型)的初始化工作,如下:

int InitObject
( SConfig* pObject, /* 指向待初始化的结构或结构数组 */
int Count /* 结构的个数 */
);

测试时发现,对于Count参数,传入负值时函数会发生异常错误,不过按正常逻辑,Count是不可能取小于零的数的。我认为应该加入对负值的判断,但我的同事认为没有必要,认为就象ANSI中的strncpy( char *strDest, const char *strSource, size_t count )函数在count取负值时同样会发生异常。
这个问题,我确实是不能肯定到底需要修改否,大家是如何看待的呢?
...全文
402 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
xjp6688 2004-07-01
  • 打赏
  • 举报
回复
up
ljux 2004-06-30
  • 打赏
  • 举报
回复
何为release和debug版本,解释一下
goodname 2004-06-30
  • 打赏
  • 举报
回复
没有完美的解决方法,我记得c++的那位创始人说过这个问题。
晨星 2004-06-30
  • 打赏
  • 举报
回复
觉得偶上面的观点有些偏了。
最近在改一堆前人的代码,发现里面有好多地方,一旦发现错误参数,要么使用缺省参数代替,要么直接让函数表现出缺省行为,觉得也不失为一种好方法。
zqy1999 2004-06-30
  • 打赏
  • 举报
回复
最后的处理结果:对于可以捕捉到的异常参数输入,API内部必须进行错误处理,对于实在无法识别的 异常参数输入(比如指针、句柄等类型的参数),API内部不做处理,但在API的使用说明中要对这种情况进行说明。

谢谢各位朋友的帮助,谢谢!
晨星 2004-06-25
  • 打赏
  • 举报
回复
To:zqy1999(秋秋)
“对于非法的指针这种问题,程序很难进行判断”

-偶还是认为,这不是什么难度上的问题。liao2001(知之为知之,不知为不知。。。) 说得对,这是个职责的问题。
库函数即使判断了非法参数,并做了处理,又能怎样呢?于事有补吗?说不定还导致了在调试阶段隐藏了Bug的问题。
ddddh 2004-06-22
  • 打赏
  • 举报
回复
个人觉得这个是见仁见智的问题。

可以诱发异常,也可以通过返回值来告诉用户您的输入有错误。

但是有一点,您的所有API,必须统一。同时在文档中需要描述清楚。

这样就可以了。
zqy1999 2004-06-21
  • 打赏
  • 举报
回复
steedhorse(晨星) 提到:“对于非法的指针,字符数,都会导致异常,但这当然不能怪库的开发者。就好比如果你随便拔掉电源导致文件未保存不能怪微软一样。”
对于非法的指针这种问题,程序很难进行判断,所以需要函数的使用者自己注意,但类似本贴的问题,程序是很容易对这种情况进行识别的,难道也不进行判断吗?
关键是函数对非法参数输入的判断到底需要做到什么程度?
liao2001 2004-06-21
  • 打赏
  • 举报
回复
个人认为assert并不是一个好主意,毕竟assert是针对于调试而产生,而且用assert也应该不是搂主的本意所希望的。
那么对于楼主提到的这种问题该怎么办呢?我也来说说自己的看法。
对于开发某个函数的程序员来说,他是没有办法限制使用该函数的程序员的行为的,他唯一能做的就是提供有效入参的范围,通常是以文档的形式出现,也有不需要文档的,比如搂主上述的,将int改成unsigned int。
有人说,如果在函数中加入入参判断的话,那函数不是更完美了吗?更何况这并不难。
这是一个职责的问题。函数的职责是实现某一个功能(单一功能),入参判断是函数调用者的职责,如果强加给函数的话,除了函数臃肿得像个贵妇人外,我看不出它有什么好的地方。那么调用者又如何知道函数的本意呢?这也就是文档的必要性了。
idontlikenickname 2004-06-19
  • 打赏
  • 举报
回复


en~
同意星哥steedhorse的意见~~

Wolf0403 2004-06-19
  • 打赏
  • 举报
回复
assert(Count >= 0); //debug版用到.
if (Count < 0 )
return FALSE; //release版用到.

这样的发生错误的时候,debug 版和 release 版会表现出完全不同的行为,我觉得这样可能不是一个好主意。
Wolf0403 2004-06-19
  • 打赏
  • 举报
回复
assert 表示的是一个 pre/post condition 的意思,就是说,代码允许到这个位置的时候“应该符合这个条件”,相当于一种给程序员看的注释
Wolf0403 2004-06-19
  • 打赏
  • 举报
回复
我觉得这样的判断应该用 assert 足以解决问题了。如果一个程序在 DEBUG 版不出现问题而 release 出现,那么就是客户程序的问题而不是你的 API 的问题了。
积木 2004-06-19
  • 打赏
  • 举报
回复
程序开发分为Debug和Release版本
如果为了这种约定东西徒劳的增加函数的复杂度我认为是不必要的
我认为断言就是为了解决这种参数传错问题而产生的
(所以我参数判错都用断言来写,很简洁)
写详细的文档吧,
这也的确是一个好方法
晨星 2004-06-19
  • 打赏
  • 举报
回复
加Assert是有必要的。
但如果库还要给别人用,那么Assert也没什么大用,因为通常我们发布的都是Release版本。

所以,最终还是需要清晰的文档说明。
晨星 2004-06-19
  • 打赏
  • 举报
回复
函数可以不作处理,但文档中一定要写清楚。
这样,故障是客户的责任;否则就是程序员的责任。

对,就像strncpy,对于非法的指针,字符数,都会导致异常,但这当然不能怪库的开发者。就好比如果你随便拔掉电源导致文件未保存不能怪微软一样。
zjxiaoyu 2004-06-18
  • 打赏
  • 举报
回复
如果光用c的话.
可以
Bool InitObject
( SConfig* pObject, /* 指向待初始化的结构或结构数组 */
int Count /* 结构的个数 */
)
{
assert(Count >= 0); //debug版用到.
if (Count < 0 )
return FALSE; //release版用到.

...
return TRUE;
}
或者如果还想知道更多的错误信息的话,返回错误类型.
如果返回值有别的用处的话,改接口.
Bool InitObject
( SConfig* pObject, /* 指向待初始化的结构或结构数组 */
int Count, /* 结构的个数 */
int &ErrCode /*自己的程序填这个ErrCode*/
);
类似问题我好像在哪期<<程序员>>上看到过..
(ps.他建议接口做成c语言风格的)
peter9606 2004-06-18
  • 打赏
  • 举报
回复
我看 既然是这样
那就应该在函数中做出相应的对于非法参数的 错误处理
最好是异常
541145 2004-06-18
  • 打赏
  • 举报
回复
应该判断
可以用 assert(condition) ;
zqy1999 2004-06-18
  • 打赏
  • 举报
回复
这套函数库是做为产品来开发的,不光我们内部用,也会有客户购买这套API。
在这套函数库里类似于这样的问题不少,现在正不知道是否要作为一个问题提出来呢。
加载更多回复(3)

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧