struct my_struct *p = (struct my_struct *)malloc(sizeof(struct my_struct));

C

Chris Fogelklou

What is wrong with the above?

Don't worry, I already know (learned my lesson last week.) It is for the
benefit of our resident compiler guru who seems to think you need the cast.
I thought it too, up until I started posting here!

Thanks,

Chris
 
C

Chris Fogelklou

Chris Fogelklou said:
What is wrong with the above?

Don't worry, I already know (learned my lesson last week.) It is for the
benefit of our resident compiler guru who seems to think you need the cast.
I thought it too, up until I started posting here!

Thanks,

Chris
Even better, here is the email itself. Please help!

<start email>
First, Casts from void * are necessary both in C and C++. This is from the
same reason you told me: otherwise, if the compiler wouldn't
know what is the size of the object which is pointed at, it might get
confused with arithmetic operations. You can ask him where did he learned
this rule from. tell me if you want me to correspond directly with him.

Second, a possible reason to use integral types for addresses rather than
void *, is that in order to perform bitwise operations on an
address, you have to use operators of an integral type.
<end email>
 
R

Régis Troadec

Chris Fogelklou said:
Hi,

Even better, here is the email itself. Please help!

<start email>
First, Casts from void * are necessary both in C and C++. This is from the

Casts from void* are necessary in C++, not in C.
same reason you told me: otherwise, if the compiler wouldn't
know what is the size of the object which is pointed at, it might get
confused with arithmetic operations. You can ask him where did he learned
this rule from. tell me if you want me to correspond directly with him.

Second, a possible reason to use integral types for addresses rather than
void *, is that in order to perform bitwise operations on an
address, you have to use operators of an integral type.
<end email>

Regis
 
C

Chris Fogelklou

Régis Troadec said:
the

Casts from void* are necessary in C++, not in C.

I am aware... I'm fishing for more info! Perhaps if I reposted again and
said you were wrong I'll get more...

You're WRONG!
 
T

Thomas Stegen

Chris said:
Even better, here is the email itself. Please help!

<start email>
First, Casts from void * are necessary both in C and C++. This is from the
same reason you told me: otherwise, if the compiler wouldn't
know what is the size of the object which is pointed at, it might get
confused with arithmetic operations. You can ask him where did he learned
this rule from. tell me if you want me to correspond directly with him.

Yes, please tell her to come here. On the other hand, don't, tell
her to read the archives. This conversation is getting old ;)

the ISO/IEC 9899:1999 standard section 6.3.2.3 has what you want. That
is C99 btw. Don't know the clause in C89.
Second, a possible reason to use integral types for addresses rather than
void *, is that in order to perform bitwise operations on an
address, you have to use operators of an integral type.

This much is true. But it is in implementation defined behaviour land,
most compilers behave very nicely when it comes to this though.
 
T

Thomas Stegen

Chris said:
What is wrong with the above?

Don't worry, I already know (learned my lesson last week.) It is for the
benefit of our resident compiler guru who seems to think you need the cast.
I thought it too, up until I started posting here!

struct my_struct *p = (struct my_struct *)malloc(sizeof(struct
my_struct));

There is nothing wrong with the above. It is considered a better
idiom to use

struct my_struct *p = malloc(sizeof *p);

The argument that the compiler does not know the type of the object
is bogus since all the information is already there. The compiler knows
the type of p, it knows the type of the value returned by malloc,
nothing is missing.

In my previous reply I mentioned 6.3.2.3, I should also have mentioned
clause 6.5.4 and 6.5.16.1 which is where the "no cast required" part is.
 
R

Régis Troadec

"Chris Fogelklou" <[email protected]> a écrit dans le message de

Yes, sorry for that, i read your post too quickly,
I am aware... I'm fishing for more info! Perhaps if I reposted again and
said you were wrong I'll get more...

You're WRONG!

void* is implicitly converted to the destination pointer type (C99 §6.3.2.3
and §7.20.3.1).

sizeof ?
You can ask him where did he
learned

It's also said in the standard (C99), part 6 of §6.3.2.3 that :
"Any pointer type may be converted to an integer type. Except as previously
specified, the result is implementation-defined. If the result cannot be
represented in the integer type, the behavior is undefined. The result need
not be in the range of values of any integer type."

Is he/she sure that he/she can always hold his adressses with an integral
type ? It implies sizeof(the famous integral type) >= sizeof(void*).

There is a way in C99 to hold pointers and adresses with integers thanks to
the types intptr_t and uintptr_t. (C99 7.18.1.4), but I'm not sure it's
possible in C90..

Regis
 
C

Chris Fogelklou

Thomas Stegen said:
struct my_struct *p = (struct my_struct *)malloc(sizeof(struct
my_struct));

There is nothing wrong with the above. It is considered a better
idiom to use

struct my_struct *p = malloc(sizeof *p);

The argument that the compiler does not know the type of the object
is bogus since all the information is already there. The compiler knows
the type of p, it knows the type of the value returned by malloc,
nothing is missing.

In my previous reply I mentioned 6.3.2.3, I should also have mentioned
clause 6.5.4 and 6.5.16.1 which is where the "no cast required" part is.

Hi Thomas,

Thanks! OK, then what about this:

int my_func(void *pinst)
{
my_struct *pthis = (my_struct *)pinst; //Cast
pthis->print("Lets see what's wrong with this!");
return 0;
}

If it is OK to never cast to/from void * as was made abundantly clear last
week, then this is also OK. However, pinst could be a run-time defineable
value.

Thanks!

Chris
 
Z

Zoran Cutura

Chris Fogelklou said:
int my_func(void *pinst)
{
my_struct *pthis = (my_struct *)pinst; //Cast
pthis->print("Lets see what's wrong with this!");
return 0;
}

If it is OK to never cast to/from void * as was made abundantly clear last
week, then this is also OK. However, pinst could be a run-time defineable
value.


It is absolutly ok to do this (presuming a correct definition of
my_struct) with or without a cast.

void * can be converted to from other object pointer types and the other
way round without casts in any circumstance. (function pointers are
different here, but that is another story).

And note that function parameters are always evaluated at runtime.

When my_func is called, the arguments to that call are evaluated and
copied into the parameters of the to be called function.
 
C

CBFalconer

Chris said:
Even better, here is the email itself. Please help!

<start email>
First, Casts from void * are necessary both in C and C++. This is
from the same reason you told me: otherwise, if the compiler
wouldn't know what is the size of the object which is pointed at,
it might get confused with arithmetic operations. You can ask him
where did he learned this rule from. tell me if you want me to
correspond directly with him.

Second, a possible reason to use integral types for addresses
rather than void *, is that in order to perform bitwise operations
on an address, you have to use operators of an integral type.
<end email>

Don't get too antsy with him/her. This sounds like some system
programming operations on some embedded system, where the rules
are often different. The cast of the malloc remains unnecessary
(and don't put the question in the subject only).

Do learn to organize your questions into a single consistent
message, rather than a bit here and a bit there.
 
C

Chris Fogelklou

Régis Troadec said:
"Chris Fogelklou" <[email protected]> a écrit dans le message de

Yes, sorry for that, i read your post too quickly,


void* is implicitly converted to the destination pointer type (C99 §6.3.2.3
and §7.20.3.1).


sizeof ?


It's also said in the standard (C99), part 6 of §6.3.2.3 that :
"Any pointer type may be converted to an integer type. Except as previously
specified, the result is implementation-defined. If the result cannot be
represented in the integer type, the behavior is undefined. The result need
not be in the range of values of any integer type."

Is he/she sure that he/she can always hold his adressses with an integral
type ? It implies sizeof(the famous integral type) >= sizeof(void*).

There is a way in C99 to hold pointers and adresses with integers thanks to
the types intptr_t and uintptr_t. (C99 7.18.1.4), but I'm not sure it's
possible in C90..

Regis
Do you know if this was also a standard in C89/C90? If so, it would
strengthen my argument since the recent response was that "GCC-derived
compilers don't fully support C99 yet." Not sure if it's true... Any
thoughts?

Not sure what she meant with arithmetic operations... you don't normally do
arithmetic on pointers, but if you did, I guess you could just cast to an
integral type of the correct size, correct?

The fact is I am very uncomfortable holding addresses in an integral data
type. Usually we let the compiler choose the addressing scheme (depending
on the memory model) and it should (if it is smart) know how big to make
pointers. But if all of our generic pointers are integral and need to be
casted to pointers, it's our own code that must know what the memory model
is.

Thanks in advance!

Chris
 
D

Dan Pop

In said:
Yes, please tell her to come here. On the other hand, don't, tell
her to read the archives. This conversation is getting old ;)

the ISO/IEC 9899:1999 standard section 6.3.2.3 has what you want.

Nope, it doesn't. It says:

1 A pointer to void may be converted to or from a pointer to any
incomplete or object type. A pointer to any incomplete or
object type may be converted to a pointer to void and back again;
the result shall compare equal to the original pointer.

But there is no mention that the conversion is automatic. Compare with

5 An integer may be converted to any pointer type. Except as
previously specified, the result is implementation-defined,
might not be correctly aligned, might not point to an entity of
the referenced type, and might be a trap representation.

6 Any pointer type may be converted to an integer type. Except as
previously specified, the result is implementation-defined. If the
result cannot be represented in the integer type, the behavior
is undefined. The result need not be in the range of values of
any integer type.

7 A pointer to an object or incomplete type may be converted to
a pointer to a different object or incomplete type.

Do you mean that these conversions are automatic, too?

Dan
 
D

Dan Pop

void* is implicitly converted to the destination pointer type (C99 §6.3.2.3
and §7.20.3.1).

You're WRONG!

There is NOTHING in C99 §6.3.2.3 or §7.20.3.1 supporting your assertion.

Dan
 
D

Dan Pop

In said:
Don't get too antsy with him/her. This sounds like some system
programming operations on some embedded system, where the rules
are often different.

It sounds more like someone confusing the C and C++ rules.

Dan
 
C

Chris Fogelklou

Chris Fogelklou said:
Hi Thomas,

Thanks! OK, then what about this:

int my_func(void *pinst)
{
my_struct *pthis = (my_struct *)pinst; //Cast
pthis->print("Lets see what's wrong with this!");
return 0;
}

If it is OK to never cast to/from void * as was made abundantly clear last
week, then this is also OK. However, pinst could be a run-time defineable
value.

Thanks!

Chris
Sorry... meant "then this is also BAD practice."
 
C

Chris Fogelklou

CBFalconer said:
Don't get too antsy with him/her. This sounds like some system
programming operations on some embedded system, where the rules
are often different. The cast of the malloc remains unnecessary
(and don't put the question in the subject only).

Do learn to organize your questions into a single consistent
message, rather than a bit here and a bit there.

Don't worry... I'm not getting antsy (lots of smileys in my email to her).
But she's the expert and I'm just the user. Good guess that it is an
embedded system; that it is!

It's easier to ask here and get exact references than to say "but I
think..." (I made the "but I think" mistake on this NG last week :)

Next time I'll put the question in the post as well.

Cheers, Chris
 
C

Chris Fogelklou

Dan Pop said:
In <[email protected]> Thomas Stegen

Nope, it doesn't. It says:

1 A pointer to void may be converted to or from a pointer to any
incomplete or object type. A pointer to any incomplete or
object type may be converted to a pointer to void and back again;
the result shall compare equal to the original pointer.

But there is no mention that the conversion is automatic. Compare with

5 An integer may be converted to any pointer type. Except as
previously specified, the result is implementation-defined,
might not be correctly aligned, might not point to an entity of
the referenced type, and might be a trap representation.

6 Any pointer type may be converted to an integer type. Except as
previously specified, the result is implementation-defined. If the
result cannot be represented in the integer type, the behavior
is undefined. The result need not be in the range of values of
any integer type.

7 A pointer to an object or incomplete type may be converted to
a pointer to a different object or incomplete type.

Do you mean that these conversions are automatic, too?

Looks to me like if 1.) is, then 7.) is as well. Both 5.) and 6.) claim
that the result is implementation defined and the behaviour might be
undefined.
 
T

Thomas Stegen

Chris said:
Looks to me like if 1.) is, then 7.) is as well. Both 5.) and 6.) claim
that the result is implementation defined and the behaviour might be
undefined.

The right section to look at would be 6.5.4 and 6.5.16.1.
 
R

Régis Troadec

Dan Pop said:
In <[email protected]> "Régis Troadec"

You're WRONG!

There is NOTHING in C99 §6.3.2.3 or §7.20.3.1 supporting your assertion.

Let's correct it : void * may be converted to a pointer to any incomplete or
object type. As well, void* may be converted from a pointer to any
incomplete or object type. This is what I read in C99 §6.3.2.3.
You were probably hurt by seeing "void* IS ... converted".

Regis
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top