是否有可能使*更安全? [英] Is it possible to make void * safer?

查看:69
本文介绍了是否有可能使*更安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是在思考C与C ++的优点。 ADT / generic

编程。关于为

ADT编写容器库的最大抱怨是void *没有提供类型安全性。它真的必须是这个

的方式吗?


你不能用虚拟指针和

确保它们在电话中一致使用?


---------


typedef struct {

size_t count;

/ * ... * /

void * data;

} array_t;


int array_push(array_t * array,void * data);

void * array_pop(array_t * array);


---------


基于这两个接口函数,我们可以在单个对象上使用
类型的array_t跟踪该参数传递给push()的类型与

相同,你可以从pop()函数中分配它。


当然,对于那些函数来说采用多个void参数或以不一致的方式使用void

参数,我们需要跟踪这些参数如何使用并最终分配/读取/从成员中读取TY pe $>
array_t。


这似乎适用于您拥有所有可用的所有

源文件的代码。然而,当你只有一个标题

文件作为预编译库的规范时,它就会崩溃。我想,因为

参数标识符在函数原型中是可选的,如果程序员选择使用某种类型的
$ b,你可能会对某些东西产生影响。 $ b可预测的无效参数命名。


无论如何,这只是一个随意的想法。我的想法充满漏洞,但它至少在C的精神上是



谢谢,


-Clint

I was just thinking about the virtues of C vs. C++ wrt. ADT/generic
programming. The biggest complaint about writing container libraries for
ADTs is that void * offers no type safety. Does it really have to be this
way?

Couldn''t you for instance track an object''s accesses with void pointers and
ensure they are used consistently across calls?

---------

typedef struct {
size_t count;
/* ... */
void *data;
} array_t;

int array_push(array_t *array, void *data);
void *array_pop(array_t *array);

---------

Based on these two interface functions, we can on an individual object of
type array_t track that the parameter passed to push() has the same type as
the one to which you would assign from the pop() function.

Of course, for functions that take multiple void arguments or use void
arguments in inconsistent ways, we would need to track how those arguments
are used and are eventually assigned/read to/from the members of type
array_t.

This would appear to work in theory for code in which you have all the
source files available. It falls apart however when you only have a header
file as a specification for a pre-compiled library. I suppose since the
parameter identifiers are optional in function prototypes that you might be
able to divine something if the programmer elects to use some sort of
predictable naming for the void arguments.

At any rate, it was just a random thought. My idea is full of holes but it
was at least in the spirit of C :)

Thanks,

-Clint

推荐答案

Clint Olsen< cl *** @ 0lsen.net>写道:

#我只是在考虑C与C ++的优点。 ADT / generic

#编程。关于为
#ADT编写容器库的最大抱怨是void *不提供类型安全性。它真的必须是这个

#方式吗?


然后不要使用C.还有其他语言很多

型安全。您甚至可以编写前端将更复杂的类型检查语言转换为C,或者租用

像我这样的人为您编写前端。


-

SM Ryan http://www.rawbw.com/~wyrmwif/

JUSTICE!

正义死了。
Clint Olsen <cl***@0lsen.net> wrote:
# I was just thinking about the virtues of C vs. C++ wrt. ADT/generic
# programming. The biggest complaint about writing container libraries for
# ADTs is that void * offers no type safety. Does it really have to be this
# way?

Then don''t use C. There are other languages that are plenty
type safe. You can even write your front end to convert
a more sophisticated type checking language into C, or hire
people like me to write a front end for you.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
JUSTICE!
Justice is dead.

Clint Olsen写道:
Clint Olsen wrote:
我只是在考虑C与C ++的优点。 ADT /通用
编程。关于为ADT编写容器库的最大抱怨是void *不提供类型安全性。它真的必须这样吗?


它不仅仅是无效*,而是<任何> *几乎没有类型

安全。那是'C'的*真正*问题w.r.t.安全。如果你想避免

void *,这不是一个问题,但是一般来说避免使用指针 - 你在$ C $ b中不会得到太多。

你不能用虚拟指针跟踪一个对象的访问吗?
确保它们在调用中一致使用?

----- ----

typedef struct {
size_t count;
/ * ... * /
void * data;
} array_t;

int array_push(array_t * array,void * data);
void * array_pop(array_t * array);

---------
I was just thinking about the virtues of C vs. C++ wrt. ADT/generic
programming. The biggest complaint about writing container libraries for
ADTs is that void * offers no type safety. Does it really have to be this
way?
Its not just void *, but <anything> * that has little to no type
safety. That''s C''s *real* problem w.r.t. safety. If you want to avoid
void *, its not a problem, but avoiding pointers in general -- you
won''t get too far in C trying that.
Couldn''t you for instance track an object''s accesses with void pointers and
ensure they are used consistently across calls?

---------

typedef struct {
size_t count;
/* ... */
void *data;
} array_t;

int array_push(array_t *array, void *data);
void *array_pop(array_t *array);

---------




其实这样做的方法如下:


struct tagarray {

size_t count ;

/ * ... * /

无效*数据;

};


extern int untyped_array_push(struct tagarray * array,void * data);

extern void * untyped_array_pop(struct tagarray * array);


然后你写下面的内容包装:


struct< name> ; _tagarrwrap {

struct tagarray generic;

}


int< name> _array_push(struct< name> _tagarrwrap *数组,< type> *数据)

{

返回untyped_array_push(& array-> generic,(void *)数据);

}


< type> *< name> _array_pop(struct< name> _tagarrwrap * array){

return(< type> *)untyped_array_pop(& array-> generic);

}


重点是这些包装器在语法上是微不足道的,你可以通过索引某些(名称,类型)来调用它们。宏。然后

你只需要使用这些包装函数。


现在,如果C语言中的任何一种语言,那将是*完美*。你

甚至可以隐藏通用模块中的struct tagarray定义

(除了通用的void *函数

实现之外,它的定义是不必要的) ,这将和你一样安全 - *除了* C

是如此毫无价值......


无论什么< type>你选择,你不会得到任何类型的安全。对于

示例,如果我们已经设置了一个int数组:


genericArrayImpl(foo,int); / *让我们说这是我们的宏* /

struct foo_tagarrwrap arrInt;

float y = 2.0; / *这不是int * /


foo_array_push(arrInt,& y);


编译器甚至不给你在这里警告你实际上并不是* b $ b *在C中有类似安全性的东西。在你被告知任何类型的错误之前,你需要使用C ++

编译器。


所以我们已经避免了*,但我们实际上并没有获得任何类型的安全,

除非我们需要使用C ++编译器。但在这种情况下,为什么不用

只需使用C ++语言功能就可以通过

模板做到这一点?


-

Paul Hsieh
http:// www。 pobox.com/~qed/
http://bstring.sf。 net /



Well actually the way to do this is as follows:

struct tagarray {
size_t count;
/* ... */
void * data;
};

extern int untyped_array_push (struct tagarray *array, void *data);
extern void *untyped_array_pop (struct tagarray *array);

Then you write the following wrappers:

struct <name>_tagarrwrap {
struct tagarray generic;
}

int <name>_array_push (struct <name>_tagarrwrap *array, <type> * data)
{
return untyped_array_push (&array->generic, (void *) data);
}

<type> * <name>_array_pop (struct <name>_tagarrwrap *array) {
return (<type> *) untyped_array_pop (&array->generic);
}

The point is that these wrappers are so syntactically trivial, that you
can invoke them as a result of some (name, type) indexed macro. Then
you just use these wrapper functions.

Now if C were any good of a language, this would be *perfect*. You
could even hide the struct tagarray definition inside a generic module
(its definition is unnecessary except for the generic void * function
implementations), this would be about as safe as you get -- *EXCEPT* C
is so worthless ...

No matter what <type> you pick, you won''t get any type safety. For
example, if we''ve set up an int array:

genericArrayImpl (foo, int); /* Let''s say this is our macro */
struct foo_tagarrwrap arrInt;
float y = 2.0; /* This is not an int */

foo_array_push (arrInt, &y);

The compiler won''t even give you a warning here. You don''t actually
*have* anything resembling typesafety in C. You need to use a C++
compiler before you are informed of any kind of an error here.

So we''ve avoided void*, but we haven''t actually gained any typesafety,
unless we require the use of a C++ compiler. But in that case, why not
simply use the C++ language capabilities to do this right via
templates?

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/


< snip>
<snip>
genericArrayImpl(foo,int); / *让我们说这是我们的宏* /
struct foo_tagarrwrap arrInt;
float y = 2.0; / *这不是一个int * /

foo_array_push(arrInt,& y);

编译器甚至不会在这里给你一个警告。你实际上并没有*在C中有类似安全性的东西。在你被告知任何类型的错误之前,你需要使用C ++
编译器。
genericArrayImpl (foo, int); /* Let''s say this is our macro */
struct foo_tagarrwrap arrInt;
float y = 2.0; /* This is not an int */

foo_array_push (arrInt, &y);

The compiler won''t even give you a warning here. You don''t actually
*have* anything resembling typesafety in C. You need to use a C++
compiler before you are informed of any kind of an error here.




嗯?隐含地从float *转换为int *是非法的,如果那是你暗示的那个

。例如,参见C99规范的6.5.16.1节。

OP发布说,void *是隐式丢弃类型安全的门户

,他是对的。



Huh? It is illegal to implicitly convert from float* to int*, if that''s what
you are hinting at. See sections 6.5.16.1 of the C99 spec, for example. The
OP posted that void* is the gateway to implicitly throwing away type safety
and he''s right.


这篇关于是否有可能使*更安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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