第一个你编译的时候如果 -O 就不会seg fault了
但是如果你return i;
如果你怎么-O都会seg fault
2010/7/12 vivian huang <vivia...@gmail.com>:
2010/7/12 vivian huang <vivia...@gmail.com>:
特别在C这样的语言里,没有异常,要对所有错误返回错误码,基本上不现实。
你返回了,调用者还不一定用呢。我主张使用Design by Contract的概念,用
assert声明对于传入参数的要求。
无论是assert还是检查,都存在局限性。设想以下例子:
struct Test {
size_t len;
char buffer[1];
};
...
Test* ptr = NULL;
...
strcmp("ABC", ptr->buffer);
现在你传的不是NULL了,而是0x00000004(32位机)!
所以,对指针的有效性进行检查基本无解。
2010/7/12 stone zhang <kelx...@gmail.com>:
--
Wu Yongwei
URL: http://wyw.dcweb.cn/
1. C库函数和系统调用, 如果你调用这些函数的时候没有检查返回值和参数, 那是你的问题。(同样适用于已经有明确约定的库, 比如gtk等)
2. 自己写的库, 自己写的库因为文档和普及的原因, 调用者不能做到了解每个参数的作用和规则, 所以可以在函数实现内部作assert检查。
3. 再好的库碰到很烂的程序员也是没有办法的。
---
Best regards,
Zhang Jiejing
1)函数参数的正确性、错误码返回应当事先约定。有些错误可以由返回值表示,有些则必须由调用方保证。
2)指针的有效性检查基本上属于理论上不可行,从而基本没有意义。
3)调用其它人的函数时请检查接口文档,及其约定的错误处理行为。如果没有对空指针有特殊约定的话(比如,许多Windows的API用空指针作为参数取得需要的缓冲区大小),调用者必须保证行为的正确性。
回到最初的例子,不认为strcmp这样的函数有比目前行为更合理的接口。调用方应当检查参数的有效性。
2010/7/12 stone zhang <kelx...@gmail.com>:
--
空对空,谁对谁错的讨论意义不大。我再总结一下我的观点:
1)函数参数的正确性、错误码返回应当事先约定。有些错误可以由返回值表示,有些则必须由调用方保证。
2)指针的有效性检查基本上属于理论上不可行,从而基本没有意义。
3)调用其它人的函数时请检查接口文档,及其约定的错误处理行为。如果没有对空指针有特殊约定的话(比如,许多Windows的API用空指针作为参数取得需要的缓冲区大小),调用者必须保证行为的正确性。
回到最初的例子,不认为strcmp这样的函数有比目前行为更合理的接口。调用方应当检查参数的有效性。
2010/7/12 Yongwei Wu <wuyo...@gmail.com>:
>> >> > 其中(2) 解决的是crash问题,
这儿我们的观点显然相左。至少空指针引发的Crash问题我不认为应由被调函数
来检查解决。
2010/7/12 stone zhang <kelx...@gmail.com>:
2010/7/12 vivian huang <vivia...@gmail.com>:
这段代码seg fault:
int main()
{
int i = strcmp( "a", NULL );
return;
}
这样又没事:
int main()
{
strcmp( "a", NULL );
return;
}
该函数没处理NULL就让我觉得很笨,又发觉这不仅笨,还很奇怪了。这样的设计难道是为了效率?
看了glibc 的代码,string/strcmp.c 这个版本对两种情况都会段错,没“赋值就错误” 的现象。
д��һ������һ���Ϊ�ĸ����裬 ��·���£�
��1�� ����/���� ������Ҫ�õ��ı���
��2�� ��鴫�ݹ����IJ���ĺϷ���
��3�� ʵ�� ����
��4�� �ͷ���Դ/ ���ء�
���ڵڶ����� ��鴫�ݹ����IJ���ĺϷ��ԡ� ��ʵ�� �����ݹ����IJ���Ϸ��� ����Բ��ò�ͬ�Ĵ��?ʽ�� ��
��1�� assert , ���� yongwei wu ˵�ġ��ó�����������
��2�� ����ѡ�����ֻ�Dz����?
��1�� �������ڴ�����ǰ�ڿ��������ڷ������⡣��2�� ����release�汾����end-user �������Dz�����crash �ġ�
�� 2010��7��12�� ����8:42��york zhuo <york...@gmail.com>д ����
�� �ں˲��̣�����Ǵ������IJ���ΪNULL���Ƿ�������һ��ϰ����BUG_ON(!NULL)ֱ����ϵͳ������ͬ��yongwei wu �ġ��ó�����������
2010/7/12 Shell Xu <shell...@gmail.com>
C ������и���֪���Ǻû��ǻ��ĸ��������С���ȡ����һ����������㣬���ﴫ��һ��ָ���ַ��ָ�룬��Ͳ��ῼ������㴫����ָ����ô�졪�����ǵ��� �߸ÿ��ǵ����顣
���������Ƶ�ʱ��Ϊʲôѹ���ǰ������һ��æ��������ΪC�����γɵ���������û�����ר�ҡ�Ȼ�����ƺ��ˣ��Ǻû��ǻ���Ҫ�����ˡ�
�� 2010��7��12�� ����2:26��vivian huang <vivia...@gmail.com>д ����
�� ���seg fault:
int main()
{
int i = strcmp( "a", NULL );
return;
}
������û�£�
int main()
{
strcmp( "a", NULL );
return;
}
�ú���û����NULL�����Ҿ��úܱ����ַ����ⲻ��������������ˡ����������ѵ���Ϊ��Ч�ʣ�
����glibc �Ĵ��룬string/strcmp.c ����汾�������������δ?û����ֵ�ʹ��� ������
--
������������ʳ�����Σ�������ϵ֮��
--
����������������������
-york.zhuo
--
����stone
char *p = NULL;
...
if (strcmp(str1, p+2) == 0)怎么办?
于 2010年07月13日 09:46, stone zhang 写道:
写好一个函数一般分为四个步骤, 套路如下:
(1) 定义/声明 函数内要用到的变量
(2) 检查传递过来的参数的合法性
(3) 实现 功能
(4) 释放资源/ 返回。
对于第二步, 检查传递过来的参数的合法性。 其实, 当传递过来的参数不合法, 你可以采用不同的处理方式阿 。
(1) assert , 就如 yongwei wu 说的“让程序早点崩溃”
(2) 可以选择继续,只是不处理。
(1) 可以用于大程序的前期开发,便于发现问题。(2) 用于release版本,对end-user 来讲,是不允许crash 的。
在 2010年7月12日 下午8:42,york zhuo <york...@gmail.com>写 道:
在 内核层编程,如果是传过来的参数为NULL(非法),我一般习惯用BUG_ON(!NULL)直接让系统崩溃,同意yongwei wu 的“让程序早点崩溃”
2010/7/12 Shell Xu <shell...@gmail.com>
C 设计上有个不知道是好还是坏的概念,叫做最小惊讶。如果一个函数告诉你,这里传递一个指向字符串的指针,他就不会考虑如果你传个空指针怎么办——那是调用 者该考虑的事情。
至于最初设计的时候为什么压根不考虑帮调用者一个忙,那是因为C语言形成的年代,大多数用户都是专家。然后库设计好了,是好还是坏都要接受了。
在 2010年7月12日 下午2:26,vivian huang <vivia...@gmail.com>写 道:
这 段代码seg fault:
int main()
{
int i = strcmp( "a", NULL );
return;
}
这样又没事:
int main()
{
strcmp( "a", NULL );
return;
}
该函数没处理NULL就让我觉得很笨,又发觉这不仅笨,还很奇怪了。这样的设计难道是为了效率?
看了glibc 的代码,string/strcmp.c 这个版本对两种情况都会段错,没“赋值就错误” 的现象。
--
无能者无所求,饱食而遨游,泛若不系之舟
--
===========
-york.zhuo
--
我是stone
在linux上好像是 2个page, 也就是小于 8096 的指针都是会segment fault的。
其实很好的方法就是在你的程序中当segment fault 的时候把stack dump出来再退出。 不过我觉得你说的这种情况(0 +
1) 的指针, 调用者应该作好检查。
---
Best regards,
Zhang Jiejing
在 2010年7月13日 上午10:07,shell <shell...@gmail.com> 写道:
> 0x00000001合法么?
> char *p = NULL;
> ...
> if (strcmp(str1, p+2) == 0)怎么办?
>
> 于 2010年07月13日 09:46, stone zhang 写道:
>
> 写好一个函数一般分为四个步骤, 套路如下:
>
> (1) 定义/声明 函数内要用到的变量
>
> (2) 检查传递过来的参数的合法性
>
> (3) 实现 功能
>
> (4) 释放资源/ 返回。
>
>
>
> 对于第二步, 检查传递过来的参数的合法性。 其实, 当传递过来的参数不合法, 你可以采用不同的处理方式阿 。
>
> (1) assert , 就如 yongwei wu 说的"让程序早点崩溃"
>
> (2) 可以选择继续,只是不处理。
>
>
> (1) 可以用于大程序的前期开发,便于发现问题。(2) 用于release版本,对end-user 来讲,是不允许crash 的。
>
>
>
>
> 在 2010年7月12日 下午8:42,york zhuo <york...@gmail.com>写 道:
>>
>> 在 内核层编程,如果是传过来的参数为NULL(非法),我一般习惯用BUG_ON(!NULL)直接让系统崩溃,同意yongwei wu
>> 的"让程序早点崩溃"
>>
>> 2010/7/12 Shell Xu <shell...@gmail.com>
>>>
>>> C
>>> 设计上有个不知道是好还是坏的概念,叫做最小惊讶。如果一个函数告诉你,这里传递一个指向字符串的指针,他就不会考虑如果你传个空指针怎么办----那是调用
>>> 者该考虑的事情。
>>> 至于最初设计的时候为什么压根不考虑帮调用者一个忙,那是因为C语言形成的年代,大多数用户都是专家。然后库设计好了,是好还是坏都要接受了。
>>>
>>> 在 2010年7月12日 下午2:26,vivian huang <vivia...@gmail.com>写 道:
>>>>
>>>> 这 段代码seg fault:
>>>>
>>>> int main()
>>>> {
>>>>
>>>> int i = strcmp( "a", NULL );
>>>> return;
>>>> }
>>>>
>>>>
>>>> 这样又没事:
>>>> int main()
>>>> {
>>>>
>>>> strcmp( "a", NULL );
>>>> return;
>>>> }
>>>>
检查指针没有意义。知道非法又如何?有比崩更好的逻辑吗?我的经验是没有。
所以不需要检查指针。
2010/7/13 stone zhang <kelx...@gmail.com>:
>>>>>> 设计上有个不知道是好还是坏的概念,叫做最小惊讶。如果一个函数告诉你,这里传递一个指向字符串的指针,他就不会考虑如果你传个空指针怎么办----那是调用
--
(理论上讲,postconditiona应当在函数的所有出口检查,包括所有的return、throw和调用其他代码时的没被catch的throw。C++里做不到。)
2010/7/13 vivian huang <vivia...@gmail.com>:
--