ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Why not just cast ptr to GC_MS_PObj_Wrapper ** and dereference it? Why cast it to void ** first?
Also, I don't understand how they are casting between the two different structs that are a different size. Does casting a PObj * to a GC_MS_PObj_Wrapper * act as some type of "overlay" that keeps the flags field from the PObj intact, and adds on the next_ptr field?
I suggest you update your code the last reference I can easliy find to that code is two years ago and there are mentions of bugs which stamp over memory and lose data. The latest supported release is 1.4 in which the code is quite different.
Code:
static void *
gc_ms_get_free_object(PARROT_INTERP, ARGMOD(Small_Object_Pool *pool))
{
ASSERT_ARGS(gc_ms_get_free_object)
PObj *ptr;
PObj *free_list = (PObj *)pool->free_list;
/* if we don't have any objects */
if (!free_list) {
(*pool->more_objects)(interp, pool);
free_list = (PObj *)pool->free_list;
}
ptr = free_list;
pool->free_list = ((GC_MS_PObj_Wrapper*)ptr)->next_ptr;
PObj_flags_SETTO(ptr, 0);
--pool->num_free_objects;
return ptr;
}
As for why the code was as you posted I can not see from here, yet I suspect there is more to this than what you have posted. Normally when something like this is done you are looking to put the address in a integer. You could ask the developers or just get the latest from the site or svn.
Quote:
Also, I don't understand how they are casting between the two different structs that are a different size.
Hehe welcome to the wonderful world of C where it is quite common. You can see it is done in the above code also but after a quick look I would really question why they are doing this as well it does not seem to gain anything here.
I suggest you update your code the last reference I can easliy find to that code is two years ago and there are mentions of bugs which stamp over memory and lose data. The latest supported release is 1.4 in which the code is quite different.
I'm using the latest SVN sources.
Quote:
As for why the code was as you posted I can not see from here, yet I suspect there is more to this than what you have posted.
I'm pretty sure this should be all that is necessary to answer my questions regarding it.
Quote:
Normally when something like this is done you are looking to put the address in a integer.
What?
Quote:
You could ask the developers
They are very busy, and this is a basic programming question, better suited to a forum for basic programming questions.
Quote:
Hehe welcome to the wonderful world of C where it is quite common. You can see it is done in the above code also but after a quick look I would really question why they are doing this as well it does not seem to gain anything here.
I'm sure it might be "quite common", but I was asking about what the purpose is.
So again, my two questions were:
Why not just cast ptr to GC_MS_PObj_Wrapper ** and dereference it? Why cast it to void ** first?
Also, I don't understand how they are casting between the two different structs that are a different size. Does casting a PObj * to a GC_MS_PObj_Wrapper * act as some type of "overlay" that keeps the flags field from the PObj intact, and adds on the next_ptr field?
static void *
gc_ms_get_free_object(PARROT_INTERP, ARGMOD(Small_Object_Pool *pool))
{
ASSERT_ARGS(gc_ms_get_free_object)
PObj *ptr;
PObj *free_list = (PObj *)pool->free_list;
/* if we don't have any objects */
if (!free_list) {
(*pool->more_objects)(interp, pool);
free_list = (PObj *)pool->free_list;
}
ptr = free_list;
pool->free_list = ((GC_MS_PObj_Wrapper*)ptr)->next_ptr;
PObj_flags_SETTO(ptr, 0);
--pool->num_free_objects;
return ptr;
}
And by the way -- that code you posted was not the same code that I am working on. That is the code for the default Mark & Sweep algorithm. The code I posted is from the Incremental Mark & Sweep algorithm.
Note the gc_ms_ vs gc_ims_ prefix on the two different functions.
This isn't a basic programming question; it's a question of programming technique for the person who wrote it.
Kevin Barry
They were basic programming questions.
I've found an answer to the first question via the C programming channel on the Freenode IRC network. The answer is, there is no reason to make that cast to void **, and that it should have just been this instead:
pool->free_list = (*(GC_MS_PObj_Wrapper **)ptr);
I got that answer from a person that was not a developer from the project. Thus, a general knowledge of C was enough to answer the question. Thus it is a generic programming question.
As far as the second question, I have yet to find an answer to that, but once again, I'm sure it's a question about C programming, and not about the particular application I'm looking at.
The question was:
Quote:
How are they are casting between the two different structs that are a different size? Does casting a PObj * to a GC_MS_PObj_Wrapper * act as some type of "overlay" that keeps the flags field from the PObj intact, and adds on the next_ptr field?
But just so it's a general programming question, I could say:
How is it possible to cast between two structs that are a different size in C? For instance, if I had two structs that looked like this:
Does casting a generic_question_struct * to a generic_question_Wrapper * act as some type of "overlay" that keeps the flags field from the generic_question_struct intact, and adds on the next_ptr field?
Thanks,
jrtayloriv
Last edited by jrtayloriv; 09-08-2009 at 05:56 PM.
Does casting a generic_question_struct * to a generic_question_Wrapper * act as some type of "overlay" that keeps the flags field from the generic_question_struct intact, and adds on the next_ptr field?
No. Quite the opposite.
C will assume that you know what you are doing; it doesn't force much on you at all.
In your example, when you cast generic_question_struct * to a generic_question_Wrapper *, then the address your cast pointer points to will be treated exactly like a generic_question_struct location. Thus, when you write to ptr->flags, you are going to write an unsigned long instead of a size_t (which might be an unsigned long, depending on your platform). If that happens to work, great. If not, you will corrupt your target structure.
In your example, when you cast generic_question_struct * to a generic_question_Wrapper *, then the address your cast pointer points to will be treated exactly like a generic_question_struct location. Thus, when you write to ptr->flags, you are going to write an unsigned long instead of a size_t (which might be an unsigned long, depending on your platform).
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.