pointers

C

chump1708

main()
{
int i;
float *pf;
pf = (float *)&i;
*pf = 100.00;
printf("n %d", i); //line 5
}


why is the output "n 0" or for that matter if I use %f in line 5, why
is the output not 100.00??
 
M

Mark McIntyre

main()
{
int i;
float *pf;
pf = (float *)&i;

undefined behaviour, pf is a pointer to float, thats not compatible
with pointer to int. From this point on, your code can behave any way
it likes and will produce garbage (though possibly misleadingly
meaningful-looking garbage).
*pf = 100.00;

writing a float into an int is also undefined.
printf("n %d", i); //line 5
why is the output "n 0"

it could be anything - on my PC it was "n 1120403456".

Its possible (I've not checked) that this is the integer
representation of two of the bytes of the IEEE representation of
100.0. Its equally possible that its utter garbage.
or for that matter if I use %f in line 5, why is the output not 100.00??

because you invoked undefined behaviour.

If you want to store a float, use a float to store it in.

Mark McIntyre
 
I

Ingo Menger

int i;
pf = (float *)&i;

The right hand side of the assignment can be translated to english: "I
promise, that the address of the int variable i is actually a pointer
to float, even if you, dear compiler, should think otherwise. For
example, you might think that it is a pointer to int, but this is
absurd, I swear."

Why do you lie to the compiler?
And if you lie, why do you complain about unexpected output, etc.

Please observe the following:

- Don't lie to the compiler!
- A pointer cast does not somehow create a pointer of the required type
from some expression. It's just a promise to the compiler, that you
know for sure, that the expression will be of the given type at
runtime.
- If you lied to the compiler, and get unexpected results, the answer
to the question "Why do I get that result?" is always "Because you lied
to the compiler."
 
C

Christopher Benson-Manica

Mark McIntyre said:
writing a float into an int is also undefined.

Am I incorrect in thinking that this quote from 6.3.1.4 (n869)
contradicts your statement?

"When a finite value of real floating type is converted to an integer
type other than _Bool, the fractional part is discarded (i.e., the value
is truncated toward zero)."

(Assuming that the integral part has a value that can be represented
by the integer type; the next sentence declares the behavior
undefined if it is not.)

So

int foo=100.00f; /* perfectly legal */
char foo=4096.00f; /* undefined */

(Of course, OP's code was broken anyway.)
 
K

Keith Thompson

Christopher Benson-Manica said:
Am I incorrect in thinking that this quote from 6.3.1.4 (n869)
contradicts your statement?

"When a finite value of real floating type is converted to an integer
type other than _Bool, the fractional part is discarded (i.e., the value
is truncated toward zero)."

No. The code in question wasn't *converting* the value, it was
storing a float directly in an int object.
(Assuming that the integral part has a value that can be represented
by the integer type; the next sentence declares the behavior
undefined if it is not.)

So

int foo=100.00f; /* perfectly legal */
Right.

char foo=4096.00f; /* undefined */

Yes, assuming CHAR_MAX < 4096.

But the code was actually doing something like this:

int n;
*(float*)&n = 42.0;
 
C

Christopher Benson-Manica

Keith Thompson said:
No. The code in question wasn't *converting* the value, it was
storing a float directly in an int object.

Is there any way to do that without invoking UB prior to the actual
store of the float in an int object (as OP's code did)?
But the code was actually doing something like this:
int n;
*(float*)&n = 42.0;

Right, I did miss the distinction between that and the quote from
n869. Thanks.
 
K

Keith Thompson

Christopher Benson-Manica said:
Is there any way to do that without invoking UB prior to the actual
store of the float in an int object (as OP's code did)?

Um, is there any way to do what?
Right, I did miss the distinction between that and the quote from
n869. Thanks.

Actually, this invokes UB because float and int may have different
sizes and alignment requirements. If you avoid that (say, by using a
malloc()ed block of memory sufficient for either), you don't get UB
unless you try to read the stored value as an int.
 
C

Christopher Benson-Manica

Um, is there any way to do what?

Store a float in an int object without inducing a conversion, as the
OP did.
Actually, this invokes UB because float and int may have different
sizes and alignment requirements. If you avoid that (say, by using a
malloc()ed block of memory sufficient for either), you don't get UB
unless you try to read the stored value as an int.

That more or less answers the question, however. Thanks.
 
K

Keith Thompson

Christopher Benson-Manica said:
Store a float in an int object without inducing a conversion, as the
OP did.

Yes, you can do it the way the OP did. Is there some reason you'd
want to? The result is unlikely to be useful.
 
M

Mark McIntyre

Is there any way to do that without invoking UB prior to the actual
store of the float in an int object (as OP's code did)?

You could probably memcpy the data in as unsigned chars, provided you
didn't exceed sizeof(int) of them.
Mark McIntyre
 
K

Keith Thompson

Keith Thompson said:
Yes, you can do it the way the OP did. Is there some reason you'd
want to? The result is unlikely to be useful.

Sorry, I wasn't thinking clearly. As I mentioned upthread, assigning
via a converted pointer:

int n;
*(float*)&n = 42.0;

can cause UB if sizeof(float)>sizeof(int), or if any alignment
requirements are violated.

Mark McIntyre correctly points out that you can avoid the alignment
problem (but not the size problem) using memcpy(); you can even do
pointer conversions and copy unsigned byte values directly if you
like.

But again, there's rarely any good reason to do so. If you want to
store a float value, float objects are designed for precisely that
purpose. Or you can use a union.
 

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
474,173
Messages
2,570,937
Members
47,481
Latest member
ElviraDoug

Latest Threads

Top