将const void *转换为void * [英] Casting const void * into void *

查看:151
本文介绍了将const void *转换为void *的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于:


typedef struct节点节点;

struct Node {

void * obj;

Node * next;

};


typedef struct Stack Stack;

struct Stack {

节点*顶部;

};


....以下是符合C的功能(我特别担心

关于演员表,因为我没有修改obj参数?


void * stack_push(Stack * s,const void * obj)

$

节点* n;


断言(s!= NULL);

断言(obj!= NULL) ;

n = malloc(sizeof * n);

if(n == NULL)

返回NULL; / *推送失败* /

n-> obj =(void *)obj;

n-> next = s-> top;

s-> top = n;

return(void *)obj; / *成功推送* /

}


我不能使struct Node的obj字段成为一个const void *,因为用户

可能会通过析构函数释放它。 (我不能释放const void *,

吧?):


void stack_destroy(Stack * s,void(* destroy)(void *))

{

节点* n,* tmp;


断言(s!= NULL);

n = s-> top;

while(n!= NULL){

tmp = n-> next;

if(destroy!= NULL)

destroy(n-> obj); / *可能会破坏==免费* /

免费(n);

n = tmp;

}

free(s);

}

Given:

typedef struct Node Node;
struct Node {
void *obj;
Node *next;
};

typedef struct Stack Stack;
struct Stack {
Node *top;
};

....is the following a conforming C function (I am particularly worried
about the casts), since I''m not modifying the obj parameter?

void *stack_push(Stack *s, const void *obj)
{
Node *n;

assert(s != NULL);
assert(obj != NULL);
n = malloc(sizeof *n);
if (n == NULL)
return NULL; /* push failed */
n->obj = (void *) obj;
n->next = s->top;
s->top = n;
return (void *) obj; /* successful push */
}

I can''t make the obj field of struct Node a const void *, since the user
will probably free it by the "destructor" (I can''t free a const void *,
right?):

void stack_destroy(Stack *s, void (*destroy)(void *))
{
Node *n, *tmp;

assert(s != NULL);
n = s->top;
while (n != NULL) {
tmp = n->next;
if (destroy != NULL)
destroy(n->obj); /* probably destroy == free */
free(n);
n = tmp;
}
free(s);
}

推荐答案



" Enrico Trippo'Porreca' < TR **** @ lombardiacom.it>在消息新闻中写道:40 ************** @ lombardiacom.it ...

"Enrico `Trippo'' Porreca" <tr****@lombardiacom.it> wrote in message news:40**************@lombardiacom.it...
鉴于:

typedef struct Node Node;
struct Node {
void * obj;
Node * next;
};

typedef struct Stack Stack;
struct Stack {<节点*顶部;
};

...以下是一个符合C的功能(我特别担心关于演员表),因为我是不修改obj参数?


如果你没有修改obj参数,那么你可以使用:

void * stack_push(Stack * s,void * obj);

而不是。这也将避免转换为(void *)。不需要的铸件

不好。
void * stack_push(Stack * s,const void * obj)
{
Node * n;

assert(s!= NULL);
断言(obj!= NULL);
n = malloc(sizeof * n);
if(n == NULL)
返回NULL; / *推送失败* /
n-> obj =(void *)obj;
n-> next = s-> top;
s-> top = n;
return(void *)obj; / *成功推送* /
}
我不能使struct Node的obj字段成为一个const void *,因为用户可能会将它释放出来;析构函数" (我不能释放const void *,
对吗?):


For,

const void * obj;

声明,

免费(n - > obj);

会产生以下信息:


"警告:从指针目标类型传递arg 1'free''丢弃限定符

void stack_destroy(Stack * s,void(* destroy)(void *))
{
节点* n,* tmp;

断言(s!= NULL);
n = s-> top;
while(n!= NULL) {
tmp = n-> next;
if(destroy!= NULL)
destroy(n-> obj); / *可能会破坏==免费* /
免费(n);
n = tmp;
}
免费(s);
}
Given:

typedef struct Node Node;
struct Node {
void *obj;
Node *next;
};

typedef struct Stack Stack;
struct Stack {
Node *top;
};

...is the following a conforming C function (I am particularly worried
about the casts), since I''m not modifying the obj parameter?
If you are not modifying the obj parameter, then you could have used:
void *stack_push(Stack *s, void *obj);
instead. This will also avoid casting to (void*). Unneccessary castings are
not good.
void *stack_push(Stack *s, const void *obj)
{
Node *n;

assert(s != NULL);
assert(obj != NULL);
n = malloc(sizeof *n);
if (n == NULL)
return NULL; /* push failed */
n->obj = (void *) obj;
n->next = s->top;
s->top = n;
return (void *) obj; /* successful push */
}

I can''t make the obj field of struct Node a const void *, since the user
will probably free it by the "destructor" (I can''t free a const void *,
right?):
For,
const void *obj;
the statement,
free ( n -> obj );
would generate the following message:

"warning: passing arg 1 of `free'' discards qualifiers from pointer target type"

void stack_destroy(Stack *s, void (*destroy)(void *))
{
Node *n, *tmp;

assert(s != NULL);
n = s->top;
while (n != NULL) {
tmp = n->next;
if (destroy != NULL)
destroy(n->obj); /* probably destroy == free */
free(n);
n = tmp;
}
free(s);
}



2004年5月31日星期一22:42:29 +0200,Enrico`Trippo''Porreca

< tr **** @ lombardiacom.it>写道:
On Mon, 31 May 2004 22:42:29 +0200, Enrico `Trippo'' Porreca
<tr****@lombardiacom.it> wrote:
鉴于:

typedef struct节点节点;
struct Node {
void * obj;
Node * next;
};

typedef struct Stack Stack;
struct Stack {
Node * top;
};

...以下是一个符合C的函数(我特别担心关于演员表),因为我没有修改obj参数?

void * stack_push(Stack * s ,const void * obj)


这说obj是指向const void的指针。由于无法修改空格,因此修改空格的唯一目的是确保函数的

调用者确实不会改变数据obj

指向。

{
节点* n;

断言(s!= NULL);
assert(obj!= NULL);
n = malloc(sizeof * n);
if(n == NULL)
返回NULL; / *推送失败* /
n-> obj =(void *)obj;
n-> next = s-> top;
s-> top = n;
return(void *)obj; / *成功推送* /
}
我不能使struct Node的obj字段成为一个const void *,因为用户可能会将它释放出来;析构函数" (我不能释放一个空洞*,
对吧?):


是什么让你觉得不对?免费不会改变

" object"的内容。指着。它将它从存在中删除,这完全不同于b $ b。你可能必须将const void *转换为一个简单的void *来

避免对不兼容的const属性进行诊断。


真正的问题仍然是你为什么要想要?这是你的意图

,你的程序中的任何功能都没有修改

n-> obj在添加到列表后指向的内容吗? />
void stack_destroy(Stack * s,void(* destroy)(void *))
{*>节点* n,* tmp;

断言(s != NULL);
n = s-> top;
while(n!= NULL){
tmp = n-> next;
if(destroy!= NULL)
destroy(n-> obj); / *可能会破坏==免费* /
免费(n);
n = tmp;
}
免费;


s指向分配的堆栈有点奇怪,因为

结构很小而且只有一个。当然,只有一个成员的结构也有点奇怪。

}
Given:

typedef struct Node Node;
struct Node {
void *obj;
Node *next;
};

typedef struct Stack Stack;
struct Stack {
Node *top;
};

...is the following a conforming C function (I am particularly worried
about the casts), since I''m not modifying the obj parameter?

void *stack_push(Stack *s, const void *obj)
This says obj is a pointer to a const void. Since there is no way to
modify a void, the only purpose served by the const is to assure the
callers of the function that you really won''t alter the data obj
points to.
{
Node *n;

assert(s != NULL);
assert(obj != NULL);
n = malloc(sizeof *n);
if (n == NULL)
return NULL; /* push failed */
n->obj = (void *) obj;
n->next = s->top;
s->top = n;
return (void *) obj; /* successful push */
}

I can''t make the obj field of struct Node a const void *, since the user
will probably free it by the "destructor" (I can''t free a const void *,
right?):
What makes you think not? Free doesn''t alter to contents of the
"object" pointed to. It deletes it from existence which is completely
different. You may have to cast the const void* to a simple void* to
avoid the diagnostic about incompatible const attributes.

The real question remains why would you want to? Is it your intent
that no function in your program ever modify the contents of whatever
n->obj points to once it has been added to the list?

void stack_destroy(Stack *s, void (*destroy)(void *))
{
Node *n, *tmp;

assert(s != NULL);
n = s->top;
while (n != NULL) {
tmp = n->next;
if (destroy != NULL)
destroy(n->obj); /* probably destroy == free */
free(n);
n = tmp;
}
free(s);
It would be a little odd for s to point to an allocated Stack since
the struct is so small and there is only one of them. Of course, it''s
also a little odd to have struct with only one member.
}




<<删除电子邮件的del>>



<<Remove the del for email>>


" Barry Schwarz" < SC ****** @ deloz.net>在消息中写道

news:c9 ********** @ 216.39.135.223 ...
"Barry Schwarz" <sc******@deloz.net> wrote in message
news:c9**********@216.39.135.223...
2004年5月31日星期一22:42:29 +0200,Enrico`Trippo''Porreca
< tr **** @ lombardiacom.it>写道:
On Mon, 31 May 2004 22:42:29 +0200, Enrico `Trippo'' Porreca
<tr****@lombardiacom.it> wrote:
鉴于:

typedef struct节点节点;
struct Node {
void * obj;
Node *下一个;
};

typedef struct Stack Stack;
struct Stack {
Node * top;
};
Given:

typedef struct Node Node;
struct Node {
void *obj;
Node *next;
};

typedef struct Stack Stack;
struct Stack {
Node *top;
};


.... s指向一个已分配的堆栈会有点奇怪,因为结构很小而且只有一个。


为什么只有一个?我没有看到任何阻止更多的东西。

当然,只有一个成员的结构也有点奇怪。

.... It would be a little odd for s to point to an allocated Stack since
the struct is so small and there is only one of them.
Why is there only one of them? I see nothing that prevents having more.
Of course, it''s also a little odd to have struct with only one member.




如果实现被适当地抽象化,它使他能够在没有调用者需要知道的情况下将其他成员添加到struct Stack中。它可以保持类型与双链表一致,这需要

是一个跟踪两端的结构。


S


-

Stephen Sprunk愚蠢的人用智能环绕自己

CCIE#3723人。聪明的人围绕着他们自己与他们不同意的K5SSS聪明人。 --Aaron Sorkin



Provided the implementation was suitably abstracted, it enables him to add
other members to struct Stack later without callers needing to know. It
also keeps types consistent with, say, a doubly-linked list, which needs to
be a struct to keep track of both ends.

S

--
Stephen Sprunk "Stupid people surround themselves with smart
CCIE #3723 people. Smart people surround themselves with
K5SSS smart people who disagree with them." --Aaron Sorkin


这篇关于将const void *转换为void *的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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