468,740 Members | 1,864 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,740 developers. It's quick & easy.

double casts

Hi,

Those familiar with Windows programming may be familiar with the windowsx.h
header. In this header macros exist that use double casts, like so (hope
this is readable):

#define ComboBox_LimitText(hwndCtl,cchLimit) \

((int)(DWORD)SendMessage((hwndCtl),CB_LIMITTEXT,(W PARAM)(int)(cchLimit),0))

Why is this? Does this help in typechecking? (I would think not).

Thanks for the info,

--
Martijn
http://www.sereneconcepts.nl
Nov 13 '05 #1
20 1987
On Sun, 2 Nov 2003 13:33:05 +0100, "Martijn"
<su*********************@hotNOFILTERmail.com> wrote in comp.lang.c:
Hi,

Those familiar with Windows programming may be familiar with the windowsx.h
header. In this header macros exist that use double casts, like so (hope
this is readable):
Your text is readable, the concept of what the code is doing is not.
#define ComboBox_LimitText(hwndCtl,cchLimit) \

((int)(DWORD)SendMessage((hwndCtl),CB_LIMITTEXT,(W PARAM)(int)(cchLimit),0))

Why is this? Does this help in typechecking? (I would think not).
Casts never help in type checking, they specifically exist to defeat
type checking.
Thanks for the info,


For a variety of reasons, Windows header files are a complete and
total mess. If you really want to delve into the details, I'd suggest
a Windows programming group or one of Microsoft's support groups.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
Nov 13 '05 #2
"Jack Klein" <ja*******@spamcop.net> wrote in message
news:on********************************@4ax.com...
On Sun, 2 Nov 2003 13:33:05 +0100, "Martijn"
<su*********************@hotNOFILTERmail.com> wrote in comp.lang.c:
Hi,

Those familiar with Windows programming may be familiar with the windowsx.h
header. In this header macros exist that use double casts, like so (hope
this is readable):


Your text is readable, the concept of what the code is doing is not.
#define ComboBox_LimitText(hwndCtl,cchLimit) \

((int)(DWORD)SendMessage((hwndCtl),CB_LIMITTEXT,(W PARAM)(int)(cchLimit),0))

Why is this? Does this help in typechecking? (I would think not).


Casts never help in type checking, they specifically exist to defeat
type checking.
Thanks for the info,


For a variety of reasons, Windows header files are a complete and
total mess. If you really want to delve into the details, I'd suggest
a Windows programming group or one of Microsoft's support groups.


That wasn't his question.

His question is this: When is it necessary, if ever, to use
a double cast?

For example:

1. (WPARM)(int)(cchLimit)

2. (WPARM)(cchLimit)

Are these two expressions *always* equivalent? Is there ever
a situation where the intermediate cast (int) is necessary
to get a "correct" final cast to (WPARM)?

Just ignore whatever "WPARM" is supposed to be and think
about the generic question of double casting versus single casting.
Don't get distracted about Windows. This is really a C question.

For you C gurus out there, what is the definitive answer?

Nov 13 '05 #3
xarax <xa***@email.com> scribbled the following:
"Jack Klein" <ja*******@spamcop.net> wrote in message
news:on********************************@4ax.com...
On Sun, 2 Nov 2003 13:33:05 +0100, "Martijn"
<su*********************@hotNOFILTERmail.com> wrote in comp.lang.c:
> Hi,
>
> Those familiar with Windows programming may be familiar with the windowsx.h
> header. In this header macros exist that use double casts, like so (hope
> this is readable):
Your text is readable, the concept of what the code is doing is not.
> #define ComboBox_LimitText(hwndCtl,cchLimit) \
>
> ((int)(DWORD)SendMessage((hwndCtl),CB_LIMITTEXT,(W PARAM)(int)(cchLimit),0))
>
> Why is this? Does this help in typechecking? (I would think not).


Casts never help in type checking, they specifically exist to defeat
type checking.
> Thanks for the info,


For a variety of reasons, Windows header files are a complete and
total mess. If you really want to delve into the details, I'd suggest
a Windows programming group or one of Microsoft's support groups.

That wasn't his question. His question is this: When is it necessary, if ever, to use
a double cast? For example: 1. (WPARM)(int)(cchLimit) 2. (WPARM)(cchLimit) Are these two expressions *always* equivalent? Is there ever
a situation where the intermediate cast (int) is necessary
to get a "correct" final cast to (WPARM)? Just ignore whatever "WPARM" is supposed to be and think
about the generic question of double casting versus single casting.
Don't get distracted about Windows. This is really a C question. For you C gurus out there, what is the definitive answer?


I am not a C guru and cannot answer the OP's question, but I can say
for certain that in general, an expression of the type (A)(B)something
is not the same thing as (A)something.
Proof:
int i;
int *p1 = (int *)&i;
int *p2 = (int *)(long)&i;
p1 is guaranteed to store i's address. p2 is not.

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"We're women. We've got double standards to live up to."
- Ally McBeal
Nov 13 '05 #4
Joona I Palaste <pa*****@cc.helsinki.fi> writes:
[...]
I am not a C guru and cannot answer the OP's question, but I can say
for certain that in general, an expression of the type (A)(B)something
is not the same thing as (A)something.
Proof:
int i;
int *p1 = (int *)&i;
int *p2 = (int *)(long)&i;
p1 is guaranteed to store i's address. p2 is not.


Ok, that's a good example of when a double cast is harmful. Are there
any cases where it's helpful -- i.e., where (A)(B)something differs
from (A)something *and* (A)(B)something does something useful that
(A)something does not. In other words, if I see (A)(B)something in
source code, can I always delete the "(B)" without breaking anything?

Here's one example (assume 8-bit char):

unsigned int n = 257;
float f0 = (float)n; /* f0 == 257.0 */
float f1 = (float)(unsigned char)n; /* f1 == 1.0 */

Are there any examples not involving deliberate loss of information?

--
Keith Thompson (The_Other_Keith) ks*@cts.com <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 13 '05 #5
xarax wrote:
"Jack Klein" <ja*******@spamcop.net> wrote in message
"Martijn" <su*********************@hotNOFILTERmail.com> wrote:

Those familiar with Windows programming may be familiar with
the windowsx.h header. In this header macros exist that use
double casts, like so (hope this is readable):

#define ComboBox_LimitText(hwndCtl,cchLimit) \

((int)(DWORD)SendMessage((hwndCtl),CB_LIMITTEXT,(W PARAM)(int)(cchLimit),0))

Why is this? Does this help in typechecking? (I would think
not).


Casts never help in type checking, they specifically exist to
defeat type checking.

For a variety of reasons, Windows header files are a complete
and total mess. If you really want to delve into the details,
I'd suggest a Windows programming group or one of Microsoft's
support groups.


That wasn't his question.

His question is this: When is it necessary, if ever, to use
a double cast?

For example:

1. (WPARM)(int)(cchLimit)
2. (WPARM)(cchLimit)

Are these two expressions *always* equivalent? Is there ever
a situation where the intermediate cast (int) is necessary
to get a "correct" final cast to (WPARM)?

Just ignore whatever "WPARM" is supposed to be and think
about the generic question of double casting versus single
casting. Don't get distracted about Windows. This is really
a C question.

For you C gurus out there, what is the definitive answer?


One possibility that occurs to me is when you don't know the
signedness of the original item. Thus you might need:

(size_t) ((unsigned char) ch)

which could avoid generating a large number from '\0xff', say.

However the essential illegitimacy of windows headers remains :-)

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 13 '05 #6
On Sun, 02 Nov 2003 20:45:22 +0000, Keith Thompson wrote:
Joona I Palaste <pa*****@cc.helsinki.fi> writes:
[...]
I am not a C guru and cannot answer the OP's question, but I can say
for certain that in general, an expression of the type (A)(B)something
is not the same thing as (A)something.
Proof:
int i;
int *p1 = (int *)&i;
int *p2 = (int *)(long)&i;
p1 is guaranteed to store i's address. p2 is not.


Ok, that's a good example of when a double cast is harmful. Are there
any cases where it's helpful -- i.e., where (A)(B)something differs
from (A)something *and* (A)(B)something does something useful that
(A)something does not. In other words, if I see (A)(B)something in
source code, can I always delete the "(B)" without breaking anything?

Here's one example (assume 8-bit char):

unsigned int n = 257;
float f0 = (float)n; /* f0 == 257.0 */
float f1 = (float)(unsigned char)n; /* f1 == 1.0 */

Are there any examples not involving deliberate loss of information?


I have some code that uses a few double casts, but they rely on
implementation-defined behavior -- specifically that an unsigned
integer cast to a signed integer becomes the signed integer value
with the same bit value as the unsigned integer.

i.e.:
unsigned char uc = 255;
signed char sc = (signed char)uc;
/* sc has value -1 */

The code does things like this:

short s;
unsigned char uca, ucb;
...
++uca; /* increment with intended wrap from 255 to 0 */
...
--ucb; /* decrement with intended wrap from 0 to 255 */
...
s = (short)(signed char)uca + (short)(signed char)ucb;

The (signed char) casts are necessary to force the two
values being added into the range -128..+127 and the (short)
casts are necessary to prevent problems when the sum would
overflow a signed char.
Nov 13 '05 #7
Sheldon Simms <sh**********@yahoo.com> wrote in message news:<pa****************************@yahoo.com>...
....
unsigned char uc = 255;
signed char sc = (signed char)uc;
/* sc has value -1 */


There is no standard guarantee that sc has the value -1.

If 255 <= SCHAR_MAX, then sc gets the value 255, otherwise 255 is
converted in an implementation defined way. [C99 allows an
implementation defined signal to be raised, although that's highly
unlikely.]

--
Peter
Nov 13 '05 #8
On Sun, 02 Nov 2003 18:05:24 -0800, Peter Nilsson wrote:
Sheldon Simms <sh**********@yahoo.com> wrote in message news:<pa****************************@yahoo.com>...
...
unsigned char uc = 255;
signed char sc = (signed char)uc;
/* sc has value -1 */


There is no standard guarantee that sc has the value -1.

If 255 <= SCHAR_MAX, then sc gets the value 255, otherwise 255 is
converted in an implementation defined way. [C99 allows an
implementation defined signal to be raised, although that's highly
unlikely.]


Thanks for pointing that out, even though I had already said that
my code relied on implementation defined behavior. Since you didn't
bother quoting it, here's what I said:
I have some code that uses a few double casts, but they rely on
implementation-defined behavior


-Sheldon

Nov 13 '05 #9
"Sheldon Simms" <sh**********@yahoo.com> wrote in message
news:pa****************************@yahoo.com...
On Sun, 02 Nov 2003 18:05:24 -0800, Peter Nilsson wrote:
Sheldon Simms <sh**********@yahoo.com> wrote in message news:<pa****************************@yahoo.com>...
...
unsigned char uc = 255;
signed char sc = (signed char)uc;
/* sc has value -1 */


There is no standard guarantee that sc has the value -1.

If 255 <= SCHAR_MAX, then sc gets the value 255, otherwise 255 is
converted in an implementation defined way. [C99 allows an
implementation defined signal to be raised, although that's highly
unlikely.]


Thanks for pointing that out, even though I had already said that
my code relied on implementation defined behavior.

Since you didn't bother quoting it, here's what I said:


It's not that I didn't bother; I wanted to isolate the specific code that my
comment referred to.
I have some code that uses a few double casts, but they rely on
implementation-defined behavior
Continued by...
--specifically that an unsigned
integer cast to a signed integer becomes the signed integer value
with the same bit value as the unsigned integer.


Which isn't actually enough to give sc the value -1, even on an 8 bit char
implementation. You need the further assumption of two's complement.

Even implementation specific code is worth analysing from the point of view
of trying to make it (and similar code) non implementation dependant. To do
that, we (or at least I) need to discus what those dependancies are, i.e.
what the standards guarantee, and what they don't. For me, that is the whole
point of comp.lang.c.

In any case, I apologise if you feel I misrepresented you by taking your
post too far out of context.

--
Peter
Nov 13 '05 #10
On Mon, 03 Nov 2003 23:56:49 +1100, Peter Nilsson wrote:
"Sheldon Simms" <sh**********@yahoo.com> wrote in message
news:pa****************************@yahoo.com...
On Sun, 02 Nov 2003 18:05:24 -0800, Peter Nilsson wrote:
> Sheldon Simms <sh**********@yahoo.com> wrote in message news:<pa****************************@yahoo.com>... > ...
>> unsigned char uc = 255;
>> signed char sc = (signed char)uc;
>> /* sc has value -1 */
>
> There is no standard guarantee that sc has the value -1.
>
> If 255 <= SCHAR_MAX, then sc gets the value 255, otherwise 255 is
> converted in an implementation defined way. [C99 allows an
> implementation defined signal to be raised, although that's highly
> unlikely.]


Thanks for pointing that out, even though I had already said that
my code relied on implementation defined behavior.

Since you didn't bother quoting it, here's what I said:


It's not that I didn't bother; I wanted to isolate the specific code that my
comment referred to.
>> I have some code that uses a few double casts, but they rely on
>> implementation-defined behavior
Continued by...
>> --specifically that an unsigned
>> integer cast to a signed integer becomes the signed integer value
>> with the same bit value as the unsigned integer.


Which isn't actually enough to give sc the value -1, even on an 8 bit char
implementation. You need the further assumption of two's complement.


True. I realized after posting that this sentence didn't completely
describe the kind of implementation-defined behavior I was relying on.
Nov 13 '05 #11
In <lz************@cts.com> Keith Thompson <ks*@cts.com> writes:
Ok, that's a good example of when a double cast is harmful. Are there
any cases where it's helpful -- i.e., where (A)(B)something differs
from (A)something *and* (A)(B)something does something useful that
(A)something does not. In other words, if I see (A)(B)something in
source code, can I always delete the "(B)" without breaking anything?

Here's one example (assume 8-bit char):

unsigned int n = 257;
float f0 = (float)n; /* f0 == 257.0 */
float f1 = (float)(unsigned char)n; /* f1 == 1.0 */

Are there any examples not involving deliberate loss of information?


Sure:

int n = -1;
double f0 = (double)n; /* f0 == -1.0 */
double f1 = (double)(unsigned)n; /* f1 == (double)UINT_MAX */

No information is lost. The value of n can be retrieved from the value
of f1. That is, assuming that a double's mantissa has more bits than an
unsigned.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #12
> #define ComboBox_LimitText(hwndCtl,cchLimit) \

((int)(DWORD)SendMessage((hwndCtl),CB_LIMITTEXT,(W PARAM)(int)(cchLimit),0))
Why is this? Does this help in typechecking? (I would think not).

Thanks for the info,


Thanks for everybody who gave this a thought. I guess I'll post it on one
of the MS group, see if any ex-microsoftie has anything to say about it :)

--
Martijn
http://www.sereneconcepts.nl
Nov 13 '05 #13
Joona I Palaste <pa*****@cc.helsinki.fi> wrote in message news:<bo**********@oravannahka.helsinki.fi>...
xarax <xa***@email.com> scribbled the following:
"Jack Klein" <ja*******@spamcop.net> wrote in message
news:on********************************@4ax.com...
On Sun, 2 Nov 2003 13:33:05 +0100, "Martijn"
<su*********************@hotNOFILTERmail.com> wrote in comp.lang.c:
> Hi,
>
> Those familiar with Windows programming may be familiar with the windowsx.h
> header. In this header macros exist that use double casts, like so (hope
> this is readable):

Your text is readable, the concept of what the code is doing is not.

> #define ComboBox_LimitText(hwndCtl,cchLimit) \
>
> ((int)(DWORD)SendMessage((hwndCtl),CB_LIMITTEXT,(W PARAM)(int)(cchLimit),0))
>
> Why is this? Does this help in typechecking? (I would think not).

Casts never help in type checking, they specifically exist to defeat
type checking.

> Thanks for the info,

For a variety of reasons, Windows header files are a complete and
total mess. If you really want to delve into the details, I'd suggest
a Windows programming group or one of Microsoft's support groups.

That wasn't his question.

His question is this: When is it necessary, if ever, to use
a double cast?

For example:

1. (WPARM)(int)(cchLimit)

2. (WPARM)(cchLimit)

Are these two expressions *always* equivalent? Is there ever
a situation where the intermediate cast (int) is necessary
to get a "correct" final cast to (WPARM)?

Just ignore whatever "WPARM" is supposed to be and think
about the generic question of double casting versus single casting.
Don't get distracted about Windows. This is really a C question.

For you C gurus out there, what is the definitive answer?


I am not a C guru and cannot answer the OP's question, but I can say
for certain that in general, an expression of the type (A)(B)something
is not the same thing as (A)something.
Proof:
int i;
int *p1 = (int *)&i;
int *p2 = (int *)(long)&i;
p1 is guaranteed to store i's address. p2 is not.


why would the long mess this up? if i's address can be represented as
long, then wouldn't that be perfectly okay?

- nethlek
Nov 13 '05 #14
Mantorok Redgormor <ne*****@tokyo.com> scribbled the following:
Joona I Palaste <pa*****@cc.helsinki.fi> wrote in message news:<bo**********@oravannahka.helsinki.fi>...
I am not a C guru and cannot answer the OP's question, but I can say
for certain that in general, an expression of the type (A)(B)something
is not the same thing as (A)something.
Proof:
int i;
int *p1 = (int *)&i;
int *p2 = (int *)(long)&i;
p1 is guaranteed to store i's address. p2 is not.
why would the long mess this up? if i's address can be represented as
long, then wouldn't that be perfectly okay?


IF i's address can be represented as long. That's a mighty big IF you
got there.
And even if that's true, there's no guarantee the host CPU returns
scalars and pointers in the same way. It could use different registers,
for instance, in which case p2 will be pure garbage.

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"'I' is the most beautiful word in the world."
- John Nordberg
Nov 13 '05 #15
In <bo**********@oravannahka.helsinki.fi> Joona I Palaste <pa*****@cc.helsinki.fi> writes:
Mantorok Redgormor <ne*****@tokyo.com> scribbled the following:
Joona I Palaste <pa*****@cc.helsinki.fi> wrote in message news:<bo**********@oravannahka.helsinki.fi>...
I am not a C guru and cannot answer the OP's question, but I can say
for certain that in general, an expression of the type (A)(B)something
is not the same thing as (A)something.
Proof:
int i;
int *p1 = (int *)&i;
int *p2 = (int *)(long)&i;
p1 is guaranteed to store i's address. p2 is not.
why would the long mess this up? if i's address can be represented as
long, then wouldn't that be perfectly okay?


IF i's address can be represented as long. That's a mighty big IF you
got there.


And even then, there is no guarantee that the conversion between pointers
and integers (and vice versa) yields meaningful results. Only C99
provides such a guarantee, *if* intptr_t and uintptr_t are defined (and
used in the conversion) and if the pointers are void pointers. In such
a case, the code would be:

int *p2 = (void *)(intptr_t)(void *)&i;

which is kinda silly, of course. A final cast to int * is not necessary.
And even if that's true, there's no guarantee the host CPU returns
scalars and pointers in the same way. It could use different registers,
for instance, in which case p2 will be pure garbage.


Huh? I can see no function call in the code. What am I missing?

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #16
Dan Pop <Da*****@cern.ch> scribbled the following:
In <bo**********@oravannahka.helsinki.fi> Joona I Palaste <pa*****@cc.helsinki.fi> writes:
And even if that's true, there's no guarantee the host CPU returns
scalars and pointers in the same way. It could use different registers,
for instance, in which case p2 will be pure garbage.
Huh? I can see no function call in the code. What am I missing?


You're missing the fact that I can sometimes fumble up in my
terminology. By "return" I meant something like "store". Is a cast to
an (int *) allowed to read from a different register than a cast to a
(long)?

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"Ice cream sales somehow cause drownings: both happen in summer."
- Antti Voipio & Arto Wikla
Nov 13 '05 #17
In <bo**********@oravannahka.helsinki.fi> Joona I Palaste <pa*****@cc.helsinki.fi> writes:
Dan Pop <Da*****@cern.ch> scribbled the following:
In <bo**********@oravannahka.helsinki.fi> Joona I Palaste <pa*****@cc.helsinki.fi> writes:
And even if that's true, there's no guarantee the host CPU returns
scalars and pointers in the same way. It could use different registers,
for instance, in which case p2 will be pure garbage.

Huh? I can see no function call in the code. What am I missing?


You're missing the fact that I can sometimes fumble up in my
terminology. By "return" I meant something like "store". Is a cast to
an (int *) allowed to read from a different register than a cast to a
(long)?


Now, you're severely confused: the evaluation of an expression is defined
in terms of values, it is immaterial where these values are stored, as
long as all of them are obtained via legit means. It is compiler's job
to do the right thing and it has all the necessary information for that.

Such things can happen only when misdeclared functions are involved.
Consider the following *complete* program (on a C89 implementation):

int main()
{
return sin(0.0);
}

In the absence of an explicit declaration, sin() is implicitly declared
as returning int. Therefore, after generating the function call, the
compiler will expect the return value to be in whatever place a function
returning int will put its return value. But the sin() function doesn't
"know" that and it will put its return value in whatever place a function
returning double is supposed to put its return value. The final result
being that return will use an indeterminate value (but undefined behaviour
has already been invoked by the time sin() was called.

Even worse things can happen if the stack is used for passing back the
return value, because the caller generates a certain stack layout, while
the callee expects another, possibly corrupting stack data containing the
callers local variables or its return address.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #18
Dan Pop <Da*****@cern.ch> scribbled the following:
In <bo**********@oravannahka.helsinki.fi> Joona I Palaste <pa*****@cc.helsinki.fi> writes:
Dan Pop <Da*****@cern.ch> scribbled the following:
In <bo**********@oravannahka.helsinki.fi> Joona I Palaste <pa*****@cc.helsinki.fi> writes:
And even if that's true, there's no guarantee the host CPU returns
scalars and pointers in the same way. It could use different registers,
for instance, in which case p2 will be pure garbage.
Huh? I can see no function call in the code. What am I missing?


You're missing the fact that I can sometimes fumble up in my
terminology. By "return" I meant something like "store". Is a cast to
an (int *) allowed to read from a different register than a cast to a
(long)?

Now, you're severely confused: the evaluation of an expression is defined
in terms of values, it is immaterial where these values are stored, as
long as all of them are obtained via legit means. It is compiler's job
to do the right thing and it has all the necessary information for that. Such things can happen only when misdeclared functions are involved.
Consider the following *complete* program (on a C89 implementation): int main()
{
return sin(0.0);
} In the absence of an explicit declaration, sin() is implicitly declared
as returning int. Therefore, after generating the function call, the
compiler will expect the return value to be in whatever place a function
returning int will put its return value. But the sin() function doesn't
"know" that and it will put its return value in whatever place a function
returning double is supposed to put its return value. The final result
being that return will use an indeterminate value (but undefined behaviour
has already been invoked by the time sin() was called.


Thanks, Dan! You deconfused me pretty well. So in other words, when
evaluating the expressions, the compiler "knows" the correct types and
the register mix-up I was talking about can't happen. But when the
compiler is evaluating function calls, it doesn't necessarily "know" how
the return values of the functions will be used.

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"You can pick your friends, you can pick your nose, but you can't pick your
relatives."
- MAD Magazine
Nov 13 '05 #19

On Wed, 5 Nov 2003, Joona I Palaste wrote:

Dan Pop <Da*****@cern.ch> scribbled the following:
Joona I Palaste <pa*****@cc.helsinki.fi> writes:
And even if that's true, there's no guarantee the host CPU returns
scalars and pointers in the same way. It could use different registers,
for instance, in which case p2 will be pure garbage.

Huh? I can see no function call in the code. What am I missing?


You're missing the fact that I can sometimes fumble up in my
terminology. By "return" I meant something like "store". Is a cast to
an (int *) allowed to read from a different register than a cast to a
(long)?


(ITYM: Is an implementation allowed to make conversions between
[non-intptr_t] integral and pointer types do funky, unpredictable
stuff?)

Technically, yes, as long as the implementation documents that
behavior (N869 6.3.2.3#5). Of course, that would be a pretty silly
implementation; it'd be much more user-friendly to simply convert all
pointers to zero upon conversion to 'long'.

And no, no *sensible* compiler would ever do such a thing. I
don't think it would simplify anything if one made the compiler
do that.

-Arthur
Nov 13 '05 #20
In <bo*********@oravannahka.helsinki.fi> Joona I Palaste <pa*****@cc.helsinki.fi> writes:
the register mix-up I was talking about can't happen. But when the
compiler is evaluating function calls, it doesn't necessarily "know" how
the return values of the functions will be used.


Of course it knows how the return value is going to be used, but it
doesn't know how the function *really* returns this value, it has to
believe the function declaration currently in scope (which may be implicit
in C89). And if you lie to the compiler...

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

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

6 posts views Thread by Simon | last post: by
4 posts views Thread by Michael Mair | last post: by
8 posts views Thread by Quinn Kirsch | last post: by
69 posts views Thread by fieldfallow | last post: by
20 posts views Thread by mikael.liljeroth | last post: by
116 posts views Thread by Dilip | last post: by
1 post views Thread by CARIGAR | last post: by
xarzu
2 posts views Thread by xarzu | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.