新书 - '危险之C' [英] New book - 'C of Peril'

查看:69
本文介绍了新书 - '危险之C'的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,


我一直在编写一系列关于不良功能的页面,以及在C中出现的错误
随后,我现在有一本约32页的温和的小书,可以下载为PDF文件

http://www.pldaniels.com/c-of-peril


它目前仍在进行中,我总是在寻找新的

C使用不当或破坏标准功能的例子。


问候。


-

PLDaniels - 软件 - Xamime

Unix系统Internet开发ABN 19 500 721 806

PGP公钥在 http: //www.pldaniels.com/gpg-keys.pld

解决方案

文章< pa ******* *********************@pldaniels.com>,

Paul L Daniels< pl ******* @ pldaniels .COM>写道:

Hello All,

我一直在编写一系列有关不良功能的页面以及将C中出现的错误写入书中,随后,我现在有一本约32页的中等小书,可以下载为PDF文件

http://www.pldaniels.com/c-of-peril

它目前仍在进行中而且我总是在寻找使用不好或破坏标准功能的C的新例子。




我快速查看了你的文章。这是非常好的。

以下是我对几件跳过我的项目的评论。


1.

关于free()的部分,你写道:


当然,如果你试图释放一个

空指针,那么你是可以接受的在你的代码之前的某个地方,某些情况下肯定存在一些不妥之处。


当然这是令人满意的吗?不是!


我经常和有意识地释放空指针。以下是一个示例:


void somefunction(void)

{

char * x,* y,* z;


x = malloc(100);

y = malloc(100);

z = malloc(100);


if(x == NULL || y == NULL || z == NULL)

goto cleanup;


/ *在这里做一些真正的工作* /


清理:

免费(x);

免费(y);

免费(z);

}


假设第一次调用malloc()成功但是第二次

和第三次通话失败。然后使用非NULL x

调用free(),但y和z的值为NULL。这没有什么不对。

当然,有什么不对劲并不是真的。

2.

关于宏的部分,你建议:


#define foo(x){bar(x);巴兹(X); }


这不是很好。例如,以下

片段将无法编译:


if(sometest)

foo(x);

else

fubar(x);


您想将宏更改为规范形式:


#define foo(x)do {bar(x);巴兹(X); } while(0)


-

Rouben Rostamian


Up up Rouben Rostamian:< blockquote class =post_quotes> #define foo(x)do {bar(x);巴兹(X); } while(0)




如果参数有副作用,这仍会导致问题。

考虑:


#define foo(x)do {bar(x);巴兹(X); } while(0)

foo(printf(" oops!"));


如果你事先知道x的类型[0] ,你可以创建一个本地的

变量。考虑:


#define foo(x)do {int y =(x); bar(y);巴兹(y); } while(0)


然而,这又会导致变量捕获问题。考虑:


#include< stdio.h>

#define foo(x)do {int y =(x); bar(y); bar(y); } while(0)


void bar(int y){printf("%d",y); }


int main(无效){

int x,y;


x = y = 4;

foo(x + y);

printf("%d \ n",y);


返回0 ;

}


直观地说,人们会期望打印8 8 4。在我的系统上,它打印1091899344 1091899344 4,因为``foo(x +

y)''中的符号y表示内部声明'变量,这是非初始化的。


我发现阻止变量捕获的唯一解决方法是给宏变量一个晦涩的名称(例如,
) `mypackage_mymacro_myvariable'')
并希望没有其他人使用它。


[0] OT:GNU类型的扩展在这里提供了通用性。

-

-trent

支持细菌!这是有些人唯一的文化。


Rouben,


首先,感谢您的回复,随时欢迎所以你可以打赌

会有一些变化:-)

我自由地(经常和有意地)空指针。下面是一个示例:


您是否遇到依赖此行为的可移植性问题?

x = malloc(100);
y = malloc( 100);
z = malloc(100);


现在,也许这会打开一堆蠕虫,但是它不会是检查x / y / z状态的谨慎_before_继续下一个

malloc?我意识到它会使代码更长,甚至更麻烦,

然而它不是更正确。检查每个malloc后?

if(x == NULL || y == NULL || z == NULL)
goto cleanup


我可以看到有人跳过这个(goto辩论总是很有趣)。


你想把宏改成规范形式:

#define foo(x)do {bar(x);巴兹(X); } while(0)




任何人都知道是否有办法做到这一点而不依赖于do / while / if / for

(等)?


或者我们绑定这些一次性do / while循环以处理

尾随'';''?

问候。

-

PLDaniels - 软件 - Xamime

Unix系统Internet开发ABN 19 500 721 806

PGP公钥在 http: //www.pldaniels.com/gpg-keys.pld


Hello All,

I''ve been compiling a series of pages about the bad functions and
mistakes that occur in C into a book, subsequently, I now have a moderate
little book of about 32 pages available for download as a PDF file at

http://www.pldaniels.com/c-of-peril

It''s currently still being worked on and I''m always seeking out new
examples of C being used poorly or broken standard functions.

Regards.

--
PLDaniels - Software - Xamime
Unix systems Internet Development A.B.N. 19 500 721 806
PGP Public Key at http://www.pldaniels.com/gpg-keys.pld

解决方案

In article <pa****************************@pldaniels.com>,
Paul L Daniels <pl*******@pldaniels.com> wrote:

Hello All,

I''ve been compiling a series of pages about the bad functions and
mistakes that occur in C into a book, subsequently, I now have a moderate
little book of about 32 pages available for download as a PDF file at

http://www.pldaniels.com/c-of-peril

It''s currently still being worked on and I''m always seeking out new
examples of C being used poorly or broken standard functions.



I looked quickly through your writeup. It''s pretty good.
Here are my remarks on a couple of items that sort of jumped at me.

1.
On the section on free() you wrote:

Certainly it is agreeable that if you are attempting to free a
null pointer, then you''re most certainly in a situation where
somewhere prior in your code there is something amiss.

Certainly it is agreeable? Not!

I free() NULL pointers frequently and intentionally. Here is a sample:

void somefunction(void)
{
char *x, *y, *z;

x = malloc(100);
y = malloc(100);
z = malloc(100);

if (x==NULL || y==NULL || z==NULL)
goto cleanup;

/* do some real work here */

cleanup:
free(x);
free(y);
free(z);
}

Suppose that the first call to malloc() succeeds but the 2nd
and 3rd calls fail. Then free() is called with non-NULL x
but with NULL values for y and z. Nothing wrong with that.
And certainly it''s not true that "there is something amiss".
2.
On the section on macros, you suggest:

#define foo(x) { bar(x); baz(x); }

This is not really good. For example, the following
snippet will not compile:

if (sometest)
foo(x);
else
fubar(x);

You want to change the macro to the canonical form:

#define foo(x) do { bar(x); baz(x); } while(0)

--
Rouben Rostamian


Up spake Rouben Rostamian:

#define foo(x) do { bar(x); baz(x); } while(0)



This will still cause problems if the parameter has side effect(s).
Consider:

#define foo(x) do { bar(x); baz(x); } while(0)
foo (printf ("oops!"));

If you know the type of x in advance[0], you can create a local
variable. Consider:

#define foo(x) do { int y = (x); bar (y); baz (y); } while (0)

However, this in turn causes problems with variable capture. Consider:

#include <stdio.h>
#define foo(x) do { int y = (x); bar (y); bar (y); } while (0)

void bar (int y) { printf ("%d ", y); }

int main (void) {
int x, y;

x = y = 4;
foo (x + y);
printf ("%d\n", y);

return 0;
}

Intuitively, one would expect this to print "8 8 4". On my system, it
prints "1091899344 1091899344 4", because the symbol `y'' in `foo (x +
y)'' refers to the inner declaration''s variable, which is noninitialized.

The only workaround I have found to prevent variable capture is to give
the macro variable an obscure name (e.g. `mypackage_mymacro_myvariable'')
and hope nobody else uses it.

[0] OT: The GNU typeof extension provides genericity here.
--
-trent
Support bacteria! It''s the only culture some people have.


Rouben,

First up, thanks for the responses, always welcome so you can bet that
there will be some changes made :-)

I free() NULL pointers frequently and intentionally. Here is a sample:
Do you run into portability issues relying on this behavior?
x = malloc(100);
y = malloc(100);
z = malloc(100);
Now, perhaps this is going to open up a can of worms, but would it not be
prudent to check the state of x/y/z _before_ proceeding to the next
malloc? I realise that it makes for longer, possibly even messier code,
however is it not more "right" to check after each malloc?
if (x==NULL || y==NULL || z==NULL)
goto cleanup
I can see someone jumping on this one (goto debates are always amusing).

You want to change the macro to the canonical form:

#define foo(x) do { bar(x); baz(x); } while(0)



Anyone know if there''s a way to do this without relying on do/while/if/for
(etc)?

Or are we bound to these one-shot do/while loops in order to handle the
trailing '';'' ?
Regards.
--
PLDaniels - Software - Xamime
Unix systems Internet Development A.B.N. 19 500 721 806
PGP Public Key at http://www.pldaniels.com/gpg-keys.pld


这篇关于新书 - '危险之C'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆