By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,822 Members | 729 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,822 IT Pros & Developers. It's quick & easy.

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

P: n/a
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

Nov 14 '05 #1
Share this Question
Share on Google+
33 Replies


P: n/a
"Chris Fogelklou" <ch*************@comhem.se> wrote in message
news:7l********************@newsc.telia.net...
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>

Nov 14 '05 #2

P: n/a

"Chris Fogelklou" <ch*************@comhem.se> a écrit dans le message de
news:Sn********************@newsc.telia.net...
"Chris Fogelklou" <ch*************@comhem.se> wrote in message
Hi,
news:7l********************@newsc.telia.net...
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


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
Nov 14 '05 #3

P: n/a

"Régis Troadec" <re**@wanadoo.fr> wrote in message
news:c5**********@news-reader3.wanadoo.fr...

"Chris Fogelklou" <ch*************@comhem.se> a écrit dans le message de
news:Sn********************@newsc.telia.net...
"Chris Fogelklou" <ch*************@comhem.se> wrote in message
Hi,
news:7l********************@newsc.telia.net...
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
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!
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


Nov 14 '05 #4

P: n/a
Chris Fogelklou wrote:
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.

--
Thomas.
Nov 14 '05 #5

P: n/a
Chris Fogelklou wrote:
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.

--
Thomas.

Nov 14 '05 #6

P: n/a

"Chris Fogelklou" <ch*************@comhem.se> a écrit dans le message de
news:3H********************@newsc.telia.net...

Yes, sorry for that, i read your post too quickly,
"Régis Troadec" <re**@wanadoo.fr> wrote in message
news:c5**********@news-reader3.wanadoo.fr...

"Chris Fogelklou" <ch*************@comhem.se> a écrit dans le message de
news:Sn********************@newsc.telia.net...
"Chris Fogelklou" <ch*************@comhem.se> wrote in message
Hi,
news:7l********************@newsc.telia.net...
> 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

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!


void* is implicitly converted to the destination pointer type (C99 §6.3.2.3
and §7.20.3.1).
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.
sizeof ?
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.
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
<end email>


Regis

Nov 14 '05 #7

P: n/a
"Thomas Stegen" <ts*****@cis.strath.ac.uk> wrote in message
news:c5************@ID-228872.news.uni-berlin.de...
Chris Fogelklou wrote:
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.

--
Thomas.


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

Nov 14 '05 #8

P: n/a
Chris Fogelklou wrote:
"Chris Fogelklou" <ch*************@comhem.se> wrote in message
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!

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.

--
fix (vb.): 1. to paper over, obscure, hide from public view; 2.
to work around, in a way that produces unintended consequences
that are worse than the original problem. Usage: "Windows ME
fixes many of the shortcomings of Windows 98 SE". - Hutchison
Nov 14 '05 #9

P: n/a
"Régis Troadec" <re**@wanadoo.fr> wrote in message
news:c5**********@news-reader4.wanadoo.fr...

"Chris Fogelklou" <ch*************@comhem.se> a écrit dans le message de
news:3H********************@newsc.telia.net...

Yes, sorry for that, i read your post too quickly,
"Régis Troadec" <re**@wanadoo.fr> wrote in message
news:c5**********@news-reader3.wanadoo.fr...

"Chris Fogelklou" <ch*************@comhem.se> a écrit dans le message de news:Sn********************@newsc.telia.net...
> "Chris Fogelklou" <ch*************@comhem.se> wrote in message

Hi,

> news:7l********************@newsc.telia.net...
> > 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

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!


void* is implicitly converted to the destination pointer type (C99

§6.3.2.3 and §7.20.3.1).

> 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.

sizeof ?
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.
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
<end email>
>

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

Nov 14 '05 #10

P: n/a
Chris Fogelklou <ch*************@comhem.se> wrote:
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.

--
Z (Zo**********@daimlerchrysler.com)
"LISP is worth learning for the profound enlightenment experience
you will have when you finally get it; that experience will make you
a better programmer for the rest of your days." -- Eric S. Raymond
Nov 14 '05 #11

P: n/a

"Chris Fogelklou" <ch*************@comhem.se> wrote in message
news:o3********************@newsc.telia.net...
"Thomas Stegen" <ts*****@cis.strath.ac.uk> wrote in message
news:c5************@ID-228872.news.uni-berlin.de...
Chris Fogelklou wrote:
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.

--
Thomas.


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."

Nov 14 '05 #12

P: n/a
"CBFalconer" <cb********@yahoo.com> wrote in message
news:40***************@yahoo.com...
Chris Fogelklou wrote:
"Chris Fogelklou" <ch*************@comhem.se> wrote in message
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!

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.


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
Nov 14 '05 #13

P: n/a
In <c5************@ID-228872.news.uni-berlin.de> Thomas Stegen <ts*****@cis.strath.ac.uk> writes:
Chris Fogelklou wrote:
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.


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
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #14

P: n/a
In <40***************@yahoo.com> CBFalconer <cb********@yahoo.com> writes:
Chris Fogelklou wrote:
"Chris Fogelklou" <ch*************@comhem.se> wrote in message
> 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!
>

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.


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

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #15

P: n/a
In <c5**********@news-reader4.wanadoo.fr> "Régis Troadec" <re**@wanadoo.fr> writes:

"Chris Fogelklou" <ch*************@comhem.se> a écrit dans le message de
news:3H********************@newsc.telia.net...
You're WRONG!


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
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #16

P: n/a

"Dan Pop" <Da*****@cern.ch> wrote in message
news:c5**********@sunnews.cern.ch...
In <c5************@ID-228872.news.uni-berlin.de> Thomas Stegen <ts*****@cis.strath.ac.uk> writes:
Chris Fogelklou wrote:
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.


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.

Nov 14 '05 #17

P: n/a
Dan Pop wrote:
In <c5************@ID-228872.news.uni-berlin.de> Thomas Stegen <ts*****@cis.strath.ac.uk> writes:

Nope, it doesn't. It says:


I gave the other relevant sections in a different post.

--
Thomas.

Nov 14 '05 #18

P: n/a
Chris Fogelklou wrote:

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.

--
Thomas.
Nov 14 '05 #19

P: n/a

"Dan Pop" <Da*****@cern.ch> a écrit dans le message de
news:c5**********@sunnews.cern.ch...
In <c5**********@news-reader4.wanadoo.fr> "Régis Troadec" <re**@wanadoo.fr> writes:
"Chris Fogelklou" <ch*************@comhem.se> a écrit dans le message de
news:3H********************@newsc.telia.net...
You're WRONG!
void* is implicitly converted to the destination pointer type (C99 §6.3.2.3and §7.20.3.1).


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

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de

Nov 14 '05 #20

P: n/a
In <c5**********@news-reader4.wanadoo.fr> "Régis Troadec" <re**@wanadoo.fr> writes:

"Dan Pop" <Da*****@cern.ch> a écrit dans le message de
news:c5**********@sunnews.cern.ch...
In <c5**********@news-reader4.wanadoo.fr> "Régis Troadec"

<re**@wanadoo.fr> writes:

>"Chris Fogelklou" <ch*************@comhem.se> a écrit dans le message de
>news:3H********************@newsc.telia.net...
>
>> You're WRONG!
>
>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.


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".


I was hurt by not seeing *anywhere* in 6.3.2.3 that the conversion
doesn't require a cast. I am still hurt... ;-)

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #21

P: n/a
"Chris Fogelklou" <ch*************@comhem.se> wrote:
"Régis Troadec" <re**@wanadoo.fr> wrote in message <big snip>
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..


Do you know if this was also a standard in C89/C90?


intptr_t and uintptr_t are new features of C99, as is everything else
in stdint.h. They're optional features, BTW.
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?
Have a look at http://gcc.gnu.org/c99status.html.
Not sure what she meant with arithmetic operations... you don't normally do
arithmetic on pointers,
Ah, but you do, e.g. every time you use array subscription, 'walk' an
array by incrementing a pointer, add the result of the offsetof macro
to a pointer, subtract two pointers from each other, etc.
but if you did, I guess you could just cast to an
integral type of the correct size, correct?
Alas, there's no guarantee that you can cast back the result of your
operations and get a valid pointer value, so it's effectively pretty
useless. If you want to do pointer arithmetic, well, do arithmetic
on pointers. Simple, isn't it? ;-)
The fact is I am very uncomfortable holding addresses in an integral data
type.


And you're right, because you're not supposed to know anything of
the inner structure of pointers. After all, that's why pointer types
are distinct from the other types. I wouldn't be surprised if
somebody comes up with an example for an architecture where pointer
values cannot meaningfully represented in an object of any integer
type at all.

Regards
--
Irrwahn Grausewitz (ir*******@freenet.de)
welcome to clc: http://www.ungerhu.com/jxh/clc.welcome.txt
clc faq-list : http://www.faqs.org/faqs/C-faq/faq/
clc OT guide : http://benpfaff.org/writings/clc/off-topic.html
Nov 14 '05 #22

P: n/a
"Irrwahn Grausewitz" <ir*******@freenet.de> wrote in message
news:es********************************@4ax.com...
"Chris Fogelklou" <ch*************@comhem.se> wrote:
"Régis Troadec" <re**@wanadoo.fr> wrote in message

<big snip>
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..


Do you know if this was also a standard in C89/C90?


intptr_t and uintptr_t are new features of C99, as is everything else
in stdint.h. They're optional features, BTW.
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?


Have a look at http://gcc.gnu.org/c99status.html.
Not sure what she meant with arithmetic operations... you don't normally doarithmetic on pointers,


Ah, but you do, e.g. every time you use array subscription, 'walk' an
array by incrementing a pointer, add the result of the offsetof macro
to a pointer, subtract two pointers from each other, etc.
but if you did, I guess you could just cast to an
integral type of the correct size, correct?


Alas, there's no guarantee that you can cast back the result of your
operations and get a valid pointer value, so it's effectively pretty
useless. If you want to do pointer arithmetic, well, do arithmetic
on pointers. Simple, isn't it? ;-)
The fact is I am very uncomfortable holding addresses in an integral data
type.


And you're right, because you're not supposed to know anything of
the inner structure of pointers. After all, that's why pointer types
are distinct from the other types. I wouldn't be surprised if
somebody comes up with an example for an architecture where pointer
values cannot meaningfully represented in an object of any integer
type at all.

Great, thanks Irrwahn.

I guess my one unanswered question now is whether or not it was possible to
equate a void * to int * or struct my_struct * or any other type of
non-function pointer way back in C89/C90, or is that also a new addition in
C99? I can't find the C89/C90 specs anywhere on the 'net. (C99 was simple,
though.)

Eg:
int * i;
void * p;

i = malloc(sizeof(int));
*i = 5;
p = i; // would this puke under C89/C90?

Cheers,

Chris

Nov 14 '05 #23

P: n/a
"Chris Fogelklou" <ch*************@comhem.se> wrote:
<big snip>
Great, thanks Irrwahn.

I guess my one unanswered question now is whether or not it was possible to
equate a void * to int * or struct my_struct * or any other type of
non-function pointer way back in C89/C90, or is that also a new addition in
C99?
See below.
I can't find the C89/C90 specs anywhere on the 'net. (C99 was simple,
though.)
Try one of the following URLs, AFAIK they should link to plain text
renditions of the last public draft of C89:

http://danpop.home.cern.ch/danpop/ansi.c
http://www.tkn.tu-berlin.de/~jklaue/ansic
Eg:
int * i;
void * p;

i = malloc(sizeof(int));
*i = 5;
p = i; // would this puke under C89/C90?


No, it's just fine. Just to add that this rule for simple assignment
is also valid for passing parameters to (non-variadic) prototyped
functions and returning pointer values from functions; silly example:

void *foo( void *vp )
{
int *ip = vp;
return ip;
}

int main( void )
{
int i;
int *p = foo( &i );
return 0;
}

HTH
Regards
--
Irrwahn Grausewitz (ir*******@freenet.de)
welcome to clc: http://www.ungerhu.com/jxh/clc.welcome.txt
clc faq-list : http://www.faqs.org/faqs/C-faq/faq/
clc OT guide : http://benpfaff.org/writings/clc/off-topic.html
Nov 14 '05 #24

P: n/a
In article <news:o3********************@newsc.telia.net>
Chris Fogelklou <ch*************@comhem.se> writes:
... 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.


Of course, we have to assume that "my_struct" is a typedef or
#define for some structure type. (I would prefer to write out
"struct S *p" instead of "alias_for_struct_S *p" myself, which
removes the need for any such assumptions. The C style guide for
Wind River goes the other way though -- one must often conform to
externally-imposed requirements, no matter how wrong one thinks
they might be. :-) )

The above is OK provided that "pinst" really points to the structure
type, and that the "print" member really points to a function that
takes a value of type "char *" or "const char *", which in turn
does not write over any of the "char"s.

The cast can be removed with no semantic change at all in C. (The
cast may not be removed in C++, but then, even more changes are
required if the above is to be compiled as Pascal or Ada, so why
would we care? :-) )

I remain puzzled as to what "pinst could be a run-time defineable
value" *means*. In the above, "pinst" is a formal parameter of
type "void *", whose value is supplied at run time by the caller.
The value cannot be determined by inspection of my_func(). In
other words, the value stored in the object named "pinst" *is* a
"run-time value".
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #25

P: n/a
"Chris Torek" <no****@torek.net> wrote in message
news:c5********@news1.newsguy.com...
In article <news:o3********************@newsc.telia.net>
Chris Fogelklou <ch*************@comhem.se> writes:
... 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 lastweek, then this is also OK. However, pinst could be a run-time defineablevalue.
Of course, we have to assume that "my_struct" is a typedef or
#define for some structure type. (I would prefer to write out
"struct S *p" instead of "alias_for_struct_S *p" myself, which
removes the need for any such assumptions. The C style guide for
Wind River goes the other way though -- one must often conform to
externally-imposed requirements, no matter how wrong one thinks
they might be. :-) )

The above is OK provided that "pinst" really points to the structure
type, and that the "print" member really points to a function that
takes a value of type "char *" or "const char *", which in turn
does not write over any of the "char"s.

The cast can be removed with no semantic change at all in C. (The
cast may not be removed in C++, but then, even more changes are
required if the above is to be compiled as Pascal or Ada, so why
would we care? :-) )

I remain puzzled as to what "pinst could be a run-time defineable
value" *means*. In the above, "pinst" is a formal parameter of
type "void *", whose value is supplied at run time by the caller.
The value cannot be determined by inspection of my_func(). In
other words, the value stored in the object named "pinst" *is* a
"run-time value".


Hi,
Of course, we have to assume that "my_struct" is a typedef or
Yes... my_struct is typedef'd to a type... Normally it would be called
my_struct_t in our drivers.
I remain puzzled as to what "pinst could be a run-time defineable
value" *means*.
To answer the question about pinst being run-time defineable... we are
writing embedded drivers in C using OOP and inheritance.

Most of our base-level objects have a write and read function, and other
functions on top... but write and read are always in the same place, as
they are inherited. The example I gave was a stupid example, but we do have
a "xx_printf" function that takes a parameter like pinst followed by the
usual printf parameters, creates a formatted string, and then does a "write"
to the object that pinst points to. The same "printf" function could be
printing to an LCD, a UART, SPI, you name it... the object it prints to is
more or less determined at run time.
(The
cast may not be removed in C++, but then, even more changes are
required if the above is to be compiled as Pascal or Ada


Is there really that much wrong with making code compatible with both C and
C++? If we leave the cast in there, the code could be copied and pasted
into a C++ library verbatim. Dunno... is that question heritical in this
NG?
Nov 14 '05 #26

P: n/a
"Chris Fogelklou" <ch*************@comhem.se> wrote in message
news:GS********************@newsc.telia.net...
"Chris Torek" <no****@torek.net> wrote in message
news:c5********@news1.newsguy.com...
In article <news:o3********************@newsc.telia.net>
Chris Fogelklou <ch*************@comhem.se> writes:
... 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 lastweek, then this is also OK. However, pinst could be a run-time defineablevalue.


Of course, we have to assume that "my_struct" is a typedef or
#define for some structure type. (I would prefer to write out
"struct S *p" instead of "alias_for_struct_S *p" myself, which
removes the need for any such assumptions. The C style guide for
Wind River goes the other way though -- one must often conform to
externally-imposed requirements, no matter how wrong one thinks
they might be. :-) )

The above is OK provided that "pinst" really points to the structure
type, and that the "print" member really points to a function that
takes a value of type "char *" or "const char *", which in turn
does not write over any of the "char"s.

The cast can be removed with no semantic change at all in C. (The
cast may not be removed in C++, but then, even more changes are
required if the above is to be compiled as Pascal or Ada, so why
would we care? :-) )

I remain puzzled as to what "pinst could be a run-time defineable
value" *means*. In the above, "pinst" is a formal parameter of
type "void *", whose value is supplied at run time by the caller.
The value cannot be determined by inspection of my_func(). In
other words, the value stored in the object named "pinst" *is* a
"run-time value".

<snipped my own diatribe>

Sorry... Kinda missed your point the first time around. It is a run-time
value, as opposed to something created like this:

my_struct_t *ps = malloc(sizeof(my_struct_t));

This can be figured out by the compiler at compile time, something that was
pointed out by someone else in an earlier post.

Nov 14 '05 #27

P: n/a
"Chris Fogelklou" <ch*************@comhem.se> wrote:
"Chris Torek" <no****@torek.net> wrote:

<snip>
(The
cast may not be removed in C++, but then, even more changes are
required if the above is to be compiled as Pascal or Ada


Is there really that much wrong with making code compatible with both C and
C++? If we leave the cast in there, the code could be copied and pasted
into a C++ library verbatim. Dunno... is that question heritical in this
NG?


IIRC, conveniently being able to use the same code base for libraries
in C and C++ seems to be the only pro casting argument so far that has
survived the recurring flamew^H^H^H^H^H^H discussions in c.l.c about
the issue.

Regards
--
Irrwahn Grausewitz (ir*******@freenet.de)
welcome to clc: http://www.ungerhu.com/jxh/clc.welcome.txt
clc faq-list : http://www.faqs.org/faqs/C-faq/faq/
clc OT guide : http://benpfaff.org/writings/clc/off-topic.html
Nov 14 '05 #28

P: n/a
"Chris Fogelklou" <ch*************@comhem.se> writes:
"Chris Torek" <no****@torek.net> wrote in message
news:c5********@news1.newsguy.com...

[...]
(The
cast may not be removed in C++, but then, even more changes are
required if the above is to be compiled as Pascal or Ada


Is there really that much wrong with making code compatible with both C and
C++? If we leave the cast in there, the code could be copied and pasted
into a C++ library verbatim. Dunno... is that question heritical in this
NG?


I wouldn't say it's heretical, but it's certainly a bit touchy; we've
had interminable flamewars on the subject. Search the archives if
you're interested (and masochistic).

To summarize the general (but not unanimous) consensus of the
newsgroup (as I see it):

Casting the result of malloc() is almost never a good idea. In C90,
it can mask the error of failing to include the header that defines
the malloc() function, <stdlib.h>. (In C99, the lack of a visible
declaration triggers a diagnostic, so it's less of an issue, but there
aren't yet enough conforming C99 compilers that we can ignore C90 --
and the cast is no more useful in C99 than is is in C90.)

In the absence of a prototype for malloc(), the compiler assumes that
it's an external function returning int. Casting the result to an
object pointer type is likely to grab an int-sized chunk of data from
the pointer-sized function result, or even from somewhere else
altogether. Casts in general are frowned upon unless they're
absolutely necessary.

If you want to write C++, write C++. There's seldom any good reason
to use malloc() in C++, since the new operator is built into the
language (and it's easier to use and more type-safe). C++ programs
can call C functions, so it usually makes more sense to put your C
function in a library than to cut-and-paste it into a C++ source
program.

Having said that, there are some rare cases where there's a genuine
requirement to write code that can be compiled both as C and as C++.
P. J. Plauger is in that rare situation. If you really need to do it,
casting the result of malloc() may be the way to go. But unless you
really have such a requirement, and unless you understand the
drawbacks of using the cast, you probably shouldn't do it.

(ERT might jump into the discussion at this point. See the archives
for our previous responses to him.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #29

P: n/a
"Chris Fogelklou" <ch*************@comhem.se> wrote:
What is wrong with the above?
I assume by 'the above' you mean:
struct my_struct *p = (struct my_struct *)malloc(sizeof(struct my_struct));
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.


Why don't you use google or some other agent to look through past postings.
Just search for 'malloc' and 'cast'. There are several threads every week
on the topic, where it is fully explained.
<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,
You do not need to know the size of the pointed-at object, to be
able to assign a pointer. This is legal C:

#include <stdio.h>
struct foo;
void func(struct foo *p)
{
void *q = p;
printf("foo object of unknown size at %p \n", q);
}
it might get confused with arithmetic operations.
Compilers do not get confused with arithmetic operations. Maybe your
friend is thinking of arithmetic operations on void pointers, which
are undefined. This is not relevant, because you would only do arithmetic
operations on a struct pointer. A pointer to struct is not a pointer to void.
The compiler already knows how big the struct is (you even used "sizeof"
on it when calling malloc), so it can do arithmetic correctly.

If you are still unsure, do this:

#include <stdio.h>
#include <stdlib.h>
struct my_struct { /* fill in some stuff here */ };
int main(void)
{
struct my_struct *p = malloc(sizeof *p);
struct my_struct *q = p + 1;
printf("p=%p, q=%p\n", (void *)p, (void *)q);
printf("q-p = %d\n", (int)(q - p));
printf("(char*)q-(char*)p = %d\n", (int)((char*)q - (char*)p));
printf("sizeof(my_struct)=%d", (int)sizeof(struct my_struct));
return 0;
}

In fact this example would work just as well as if you had gone:
struct my_struct p[1];
proving that malloc has nothing to do with pointer arithmetic.
You can ask him where did he learned
this rule from. tell me if you want me to correspond directly with him.
The C Standard. You could also find this by reading the comp.lang.c FAQ.
(The C++ Standard is different).
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.


Bitwise operations can only be performed on integral types. If you write an
expression like (p & 1) then p is silently converted to an integral type
by the compiler.
It is non-portable to convert addresses to integral types (and may be
undefined if there is no integral type big enough to hold the pointer
value). For example, consider anything without a flat address space.

Finally, why is casting malloc's return value bad? Mainly, it suppresses
the compiler warning of malloc's prototype not being in scope (and it is
undefined behaviour to call malloc without prototype in scope, even though
it may compile correctly). This was discussed in more detail in another
thread this week. To demonstrate this, take my sample program above and
delete the "#include <stdlib.h>" line and compile it.
Also, it is harder to maintain if you change the type of what is being
allocated. That is why we prefer the form:

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

because it only mentions the type-name once.
Nov 14 '05 #30

P: n/a
In article <GS********************@newsc.telia.net>
Chris Fogelklou <ch*************@comhem.se> writes:
Is there really that much wrong with making code compatible with both C and
C++? If we leave the cast in there, the code could be copied and pasted
into a C++ library verbatim. ...


There is nothing inherently wrong with it, but I see it as a waste of
effort in most cases.

There are quite a few subtle differences between C and C++, so that
one can write programs that are syntactically valid in both languages,
compile in both languages, yet mean something different in each
language. The problem is similar to getting Americans and Brits
to understand each other: when an American committee "tables" a
subject it is put aside to stop discussion, while the British
committee "tables" the subject to bring it up and begin discussion.

(I posted an example earlier today in which "sizeof type" changes
when the code is compiled in the alternate language. Look for
"struct scopetrick".)

More typically, good C code often fails to compile at all as C++
code (because -- among other things -- it omits casts that C++
requires); and of course good C++ code generally uses "new" instead
of malloc, or -- even better -- uses container classes.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #31

P: n/a
Chris Torek wrote:
Chris Fogelklou <ch*************@comhem.se> writes:
Is there really that much wrong with making code compatible with
both C and C++? If we leave the cast in there, the code could
be copied and pasted into a C++ library verbatim. ...


There is nothing inherently wrong with it, but I see it as a
waste of effort in most cases.

There are quite a few subtle differences between C and C++, so
that one can write programs that are syntactically valid in both
languages, compile in both languages, yet mean something
different in each language. The problem is similar to getting
Americans and Brits to understand each other: when an American

....

Back when I was young and in my prime there was this amiable, but
poverty stricken Yank who met this foxy Brit chick. Nature took
its course, but then she told him: "I am getting divorced, with a
big settlement. Meet me after the divorce, but meanwhile I have
to stay pristine." And she handed him an envelope and told him to
open it after the day was over.

Well, he followed instructions, and opened it and read: "Until
7/6, noon, in Trafalger Square.". Since it was January, he went
off and did other things, such as roping calves etc., and returned
to London on 7/6. He never found her again.

She meant every word of it, and she was there on 7/6, but never
found him again.

Your mission, should you care to accept it, is to explain this
paradox. Alternate timelines or universes will not be accepted.

--
fix (vb.): 1. to paper over, obscure, hide from public view; 2.
to work around, in a way that produces unintended consequences
that are worse than the original problem. Usage: "Windows ME
fixes many of the shortcomings of Windows 98 SE". - Hutchison
Nov 14 '05 #32

P: n/a
On Fri, 16 Apr 2004 04:29:22 GMT, CBFalconer <cb********@yahoo.com>
wrote:
Chris Torek wrote:
Chris Fogelklou <ch*************@comhem.se> writes:
Is there really that much wrong with making code compatible with
both C and C++? If we leave the cast in there, the code could
be copied and pasted into a C++ library verbatim. ...


There is nothing inherently wrong with it, but I see it as a
waste of effort in most cases.

There are quite a few subtle differences between C and C++, so
that one can write programs that are syntactically valid in both
languages, compile in both languages, yet mean something
different in each language. The problem is similar to getting
Americans and Brits to understand each other: when an American

...

Back when I was young and in my prime there was this amiable, but
poverty stricken Yank who met this foxy Brit chick. Nature took
its course, but then she told him: "I am getting divorced, with a
big settlement. Meet me after the divorce, but meanwhile I have
to stay pristine." And she handed him an envelope and told him to
open it after the day was over.

Well, he followed instructions, and opened it and read: "Until
7/6, noon, in Trafalger Square.". Since it was January, he went
off and did other things, such as roping calves etc., and returned
to London on 7/6. He never found her again.

She meant every word of it, and she was there on 7/6, but never
found him again.

Your mission, should you care to accept it, is to explain this
paradox. Alternate timelines or universes will not be accepted.


Too easy. June 7th != July 6th. However, your language point is
evident.

--
Sev
Nov 14 '05 #33

P: n/a
In article <9g********************************@4ax.com>,
Severian <se******@chlamydia-is-not-a-flower.com> wrote:
On Fri, 16 Apr 2004 04:29:22 GMT, CBFalconer <cb********@yahoo.com>
wrote:
Chris Torek wrote:
Chris Fogelklou <ch*************@comhem.se> writes:

Is there really that much wrong with making code compatible with
both C and C++? If we leave the cast in there, the code could
be copied and pasted into a C++ library verbatim. ...

There is nothing inherently wrong with it, but I see it as a
waste of effort in most cases.

There are quite a few subtle differences between C and C++, so
that one can write programs that are syntactically valid in both
languages, compile in both languages, yet mean something
different in each language. The problem is similar to getting
Americans and Brits to understand each other: when an American

...

Back when I was young and in my prime there was this amiable, but
poverty stricken Yank who met this foxy Brit chick. Nature took
its course, but then she told him: "I am getting divorced, with a
big settlement. Meet me after the divorce, but meanwhile I have
to stay pristine." And she handed him an envelope and told him to
open it after the day was over.

Well, he followed instructions, and opened it and read: "Until
7/6, noon, in Trafalger Square.". Since it was January, he went
off and did other things, such as roping calves etc., and returned
to London on 7/6. He never found her again.

She meant every word of it, and she was there on 7/6, but never
found him again.

Your mission, should you care to accept it, is to explain this
paradox. Alternate timelines or universes will not be accepted.


Too easy. June 7th != July 6th. However, your language point is
evident.


Many years ago, a C++ framework that I investigated for its usefulness
changed a constructor from

Point::Point (int width, int height);

to

Point::Point (int vertical, int horizontal);

I decided not to use that framework...
Nov 14 '05 #34

This discussion thread is closed

Replies have been disabled for this discussion.