# plz explain

S

#### SAHIL MAHLA

#include <stdio.h>
void incme(double *p)
{
*p += 1;
}

int main(void)
{
int i = 1;
double j=i;
incme(&j);
printf("%d,%d",i,j);
return 0;
}

output is -- 1,0

it should be -1,2

plz explain

I

#### Ian Collins

SAHIL said:
#include <stdio.h>
void incme(double *p)
{
*p += 1;
}

int main(void)
{
int i = 1;
double j=i;
incme(&j);
printf("%d,%d",i,j);
return 0;
}

output is -- 1,0

it should be -1,2

Please explain why you expect this output.

E

#### Eric Sosman

#include <stdio.h>
void incme(double *p)
{
*p += 1;
}

int main(void)
{
int i = 1;
double j=i;
incme(&j);
printf("%d,%d",i,j);
return 0;
}

output is -- 1,0

That is one possible outcome. (Since the program has what
is called "undefined behavior," *all* outcomes are possible.)
it should be -1,2

I can understand why you'd expect "2", but I cannot imagine
why you'd expect "-1".
plz explain

The "%d" specifier converts `int' values, but `j' is not
an `int'. To convert a `double' value you can use "%g" (there
are other candidates, too).

K

#### Keith Thompson

SAHIL MAHLA said:
#include <stdio.h>
void incme(double *p)
{
*p += 1;
}

int main(void)
{
int i = 1;
double j=i;
incme(&j);
printf("%d,%d",i,j);
return 0;
}

output is -- 1,0

it should be -1,2

You're using a "%d" format to print a double value.

Use "%g", "%f" or "%e":

printf("%d,%g\n", i, j);

"j" is not a good name for a double variable; for historical reasons,
i and j (and probably k) are usually integers. Picking more meaningful
names might have made this problem easier to spot.

And yuou should print a newline (\n) at the end of your output.

S

#### SAHIL MAHLA

That is one possible outcome. (Since the program has what

is called "undefined behavior," *all* outcomes are possible.)

I can understand why you'd expect "2", but I cannot imagine

why you'd expect "-1".

The "%d" specifier converts `int' values, but `j' is not

an `int'. To convert a `double' value you can use "%g" (there

are other candidates, too).

Thanks for reply Eric,its '1' not '-1'.What do you mean by undefined behaviour in your comment.

K

#### Keith Thompson

Ian Collins said:
Please explain why you expect this output.

I'm fairly sure that the "-" was not meant to be part of the output,
nor was the "-- " on the preceding line.

Sahil: If you'll re-read what you wrote above, it's easy to see that
someone might assume that you though the output should be literally
"-1,2" rather than "1,2". When describing program output, it's
best to be *very* precise, so that readers can easily tell the
difference between the actual output and your text describing it.
(And in terms of English grammar, that wasn't a particularly good
place for a hyphen, or even a dash.)

I might have written something like:

The output is:
1,0
It should be:
1,2

E

#### Eric Sosman

On 3/10/2014 3:57 PM, SAHIL MAHLA wrote: [Googlespace corrected]
[...]
int main(void)
{
int i = 1;
double j=i;
incme(&j);
printf("%d,%d",i,j);
return 0;
}
[...]
That is one possible outcome. (Since the program has what
is called "undefined behavior," *all* outcomes are possible.)
[...]
What do you mean by undefined behaviour in your comment.

The C language Standard defines what a C program will do,
but only if the program "follows the rules." When the program
does something that violates the rules, the C language does not
say what will happen. Formally, the C Standard says that what
happens when the rules are broken is "undefined behavior."

Your program violates the rule that the format string for
a printf() call must match the remaining arguments. Specifically,
you have attempted to use "%d" (which requires an `int' argument)
with an argument of type `double'.

By way of analogy: You have filled your car's petrol tank
with orange juice, and the maintenance manual does not say how
much or what kind of damage that might do to the engine. After
you abuse the car, its behavior is undefined.

B

#### buja

Op maandag 10 maart 2014 20:20:38 UTC+1 schreef SAHIL MAHLA:
#include <stdio.h>

void incme(double *p)

{

*p += 1;

}

int main(void)

{

int i = 1;

double j=i;

incme(&j);

printf("%d,%d",i,j);

return 0;

}

output is -- 1,0

it should be -1,2

plz explain

Look at the compiler warnings.
GCC produced this: untitled.c:12:5: warning: format '%d' expects argument of type 'int', but argument 3 has type 'double' [-Wformat]

S

#### SAHIL MAHLA

On 3/10/2014 3:57 PM, SAHIL MAHLA wrote: [Googlespace corrected]
On 3/10/2014 3:20 PM, SAHIL MAHLA wrote:
[...]
int main(void)
{
int i = 1;
double j=i;
incme(&j);
printf("%d,%d",i,j);
return 0;
}
[...]
That is one possible outcome. (Since the program has what
is called "undefined behavior," *all* outcomes are possible.)
[...]

What do you mean by undefined behaviour in your comment.

The C language Standard defines what a C program will do,

but only if the program "follows the rules." When the program

does something that violates the rules, the C language does not

say what will happen. Formally, the C Standard says that what

happens when the rules are broken is "undefined behavior."

Your program violates the rule that the format string for

a printf() call must match the remaining arguments. Specifically,

you have attempted to use "%d" (which requires an `int' argument)

with an argument of type `double'.

By way of analogy: You have filled your car's petrol tank

with orange juice, and the maintenance manual does not say how

much or what kind of damage that might do to the engine. After

you abuse the car, its behavior is undefined.

--

Eric Sosman

#include <stdio.h>
void incme(double *p)
{
*p += 1;
}

int main(void)
{
int i = 1;
double j=i;
incme((double*)&i);
printf("%d,%g",i,j);
return 0;
}

The output is :

1,1

I feel it should be :

2,1

S

#### SAHIL MAHLA

On 3/10/2014 3:57 PM, SAHIL MAHLA wrote: [Googlespace corrected]
On 3/10/2014 3:20 PM, SAHIL MAHLA wrote:
int main(void)
int i = 1;
double j=i;
return 0;
That is one possible outcome. (Since the program has what
is called "undefined behavior," *all* outcomes are possible.)
What do you mean by undefined behaviour in your comment.
The C language Standard defines what a C program will do,
but only if the program "follows the rules." When the program
does something that violates the rules, the C language does not
say what will happen. Formally, the C Standard says that what
happens when the rules are broken is "undefined behavior."
Your program violates the rule that the format string for
a printf() call must match the remaining arguments. Specifically,
you have attempted to use "%d" (which requires an `int' argument)
with an argument of type `double'.
By way of analogy: You have filled your car's petrol tank
with orange juice, and the maintenance manual does not say how
much or what kind of damage that might do to the engine. After
you abuse the car, its behavior is undefined.

Eric Sosman

#include <stdio.h>

void incme(double *p)

{

*p += 1;

}

int main(void)

{

int i = 1;

double j=i;

incme((double*)&i);

printf("%d,%g",i,j);

return 0;

}

The output is :

1,1

I feel it should be :

2,1

in gcc compiler output is :

0,1

Why the value of i is '0'

B

#### Barry Schwarz

On Mon, 10 Mar 2014 14:31:29 -0700 (PDT), SAHIL MAHLA

snip 80 irrelevant lines

Please trim your posts. There is no point in repeating text that is

#include <stdio.h>
void incme(double *p)
{
*p += 1;

p is supposed to contain the address of a double. You have passed it
the address of an int. A typical size for an int is 4. A typical
size for a double is 8. What do you expect to happen when this line
of code attempts to access 8 bytes of an object that is only 4 bytes
wide? What do expect to happen when it tries to store the 8 byte
result into the same 4 byte wide object?
}

int main(void)
{
int i = 1;
double j=i;
incme((double*)&i);

What makes you think that &i is a valid value for a double*? Many
systems have different alignment requirements for int and double.
printf("%d,%g",i,j);

Even if int and double were the same size, you stored a floating point
value in i. What makes you think the bit pattern of that double value
is the same bit pattern as the corresponding int value.
return 0;
}

The output is :

1,1

I feel it should be :

2,1

On what do you base this feeling? Wishful thinking? You need to read
the C frequently asked questions (www.c-faq.com) and the standard
(google for the freely available draft n1570) and understand them
before your feelings have any relevance.

K

#### Keith Thompson

Eric Sosman said:
On 3/10/2014 3:57 PM, SAHIL MAHLA wrote: [Googlespace corrected] [...]
What do you mean by undefined behaviour in your comment.

The C language Standard defines what a C program will do,
but only if the program "follows the rules." When the program
does something that violates the rules, the C language does not
say what will happen. Formally, the C Standard says that what
happens when the rules are broken is "undefined behavior."

To expand on that a bit, *some* rule violations require a diagnostic
from the compiler. The diagnostic may be a warning or a fatal error.
Syntax errors are an example of this, as are various semantic errors
like trying to multiply two strings.

If your program violates a rule that requires a diagnostic, the compiler
may reject it; if it chooses to accept it, its runtime behavior is
undefined.

If your program violates a rule that doesn't require a diagnostic, the
compiler can do anything it likes; again, the runtime behavior is
undefined. The difference is that the compiler isn't required to
diagnose the error for you.

Some compilers will diagnose some such errors, even though they aren't
required to. For example, gcc can often warn about incorrect printf
format strings.

The comp.lang.c FAQ is at http://www.c-faq.com/; questions 11.33,
11.33b, 11.34, and 11.35 are particularly relevant to your question.

G

#### glen herrmannsfeldt

Barry Schwarz said:
On Mon, 10 Mar 2014 14:31:29 -0700 (PDT), SAHIL MAHLA
(snip)
snip 80 irrelevant lines
Please trim your posts. There is no point in repeating text that is

(good idea!)

(snip)
p is supposed to contain the address of a double. You have passed it
the address of an int. A typical size for an int is 4. A typical
size for a double is 8. What do you expect to happen when this line
of code attempts to access 8 bytes of an object that is only 4 bytes
wide? What do expect to happen when it tries to store the 8 byte
result into the same 4 byte wide object?

Learning C after some years of assembly programming, learning to
use pointers in C was pretty easy. It is a little different from
some other languages, though.

(snip)
What makes you think that &i is a valid value for a double*? Many
systems have different alignment requirements for int and double.

There aren't many places where a beginning C programmer should need
to cast pointers. For intermediate level, you should always recast to
the original pointer type before using it.
Even if int and double were the same size, you stored a floating point
value in i. What makes you think the bit pattern of that double value
is the same bit pattern as the corresponding int value.
(snip)

On what do you base this feeling? Wishful thinking? You need to read
the C frequently asked questions (www.c-faq.com) and the standard
(google for the freely available draft n1570) and understand them
before your feelings have any relevance.

-- glen

L

#### Lew Pitcher

On 3/10/2014 3:57 PM, SAHIL MAHLA wrote: [Googlespace corrected]
20 PM, SAHIL MAHLA wrote:
[...]
int main(void)
{
int i = 1;
double j=i;
incme(&j);
printf("%d,%d",i,j);
return 0;
}
[...]
That is one possible outcome. (Since the program has what
is called "undefined behavior," *all* outcomes are possible.)
[...]
What do you mean by undefined behaviour in your comment.
The C language Standard defines what a C program will do,
but only if the program "follows the rules." When the program
does something that violates the rules, the C language does not
say what will happen. Formally, the C Standard says that what
happens when the rules are broken is "undefined behavior."
Your program violates the rule that the format string for
a printf() call must match the remaining arguments. Specifically,
you have attempted to use "%d" (which requires an `int' argument)
with an argument of type `double'.
By way of analogy: You have filled your car's petrol tank
with orange juice, and the maintenance manual does not say how
much or what kind of damage that might do to the engine. After
you abuse the car, its behavior is undefined.
[snip]

#include <stdio.h>

void incme(double *p)
{
*p += 1;
}

int main(void)
{
int i = 1;
double j=i;
incme((double*)&i);
printf("%d,%g",i,j);
return 0;
}

The output is :
1,1

I feel it should be :
2,1

in gcc compiler output is :

0,1

Why the value of i is '0'

Why not? When you lie to the computer, it can do anything, including
returning (what seem to you to be) wrong answers.

You lied to the computer when you told it (through casting trickery) that a
pointer to an integer was actually a pointer to a double. In one place, the
computer treated it as a double, while in another place, it interpreted it
as an integer. The contents of storage are interpreted differently with
each storage type; integers are not represented in the same way doubles
are.

G

#### glen herrmannsfeldt

(snip)
Why not? When you lie to the computer, it can do anything, including
returning (what seem to you to be) wrong answers.
You lied to the computer when you told it (through casting trickery) that a
pointer to an integer was actually a pointer to a double. In one place, the
computer treated it as a double, while in another place, it interpreted it
as an integer. The contents of storage are interpreted differently with
each storage type; integers are not represented in the same way doubles
are.

There have been computers where integers within the appropriate
range had the same representation as the floating poing values.

I don't know that any are still in production, though.

Look at the Burroughs B5500, for example. I suppose there is no C
compiler for it.

-- glen

K

#### Kaz Kylheku

There have been computers where integers within the appropriate
range had the same representation as the floating poing values.

You've given me an idea.

What values of int have the same representation in float?

#include <stdio.h>
#include <limits.h>
#include <string.h>

int main(void)
{
int i;
float f;

for (i = INT_MIN; i < INT_MAX; i++) {
memcpy(&f, &i, sizeof f);
if (f == (float) i)
printf("%d (0x%x) (float->int %d)\n", i, i, (int) f);
}
return 0;
}

On this x86 Ubuntu Virtual machine here:

-834214802 (0xce46e46e) (float->int -834214784)
0 (0x0) (float->int 0)
1318926965 (0x4e9d3a75) (float->int 1318926976)

They don't agree in the reverse conversion, but close.

Let's check that last one.

0 10011101 00111010011101001110101

Exponent less 127: 2^30

Mantissa: 1915509

Crunch these through using exact rational math under Lisp:

(+ (* (expt 2 30) (+ 1 (/ 1915509 (expt 2 23)))))
-> 1318926976

L

#### Lew Pitcher

You've given me an idea.

What values of int have the same representation in float?

#include <stdio.h>
#include <limits.h>
#include <string.h>

int main(void)
{
int i;
float f;

for (i = INT_MIN; i < INT_MAX; i++) {
memcpy(&f, &i, sizeof f);

What if sizeof(float) != sizeof(int) ?

K

#### Kaz Kylheku

What if sizeof(float) != sizeof(int) ?

That can't happen because that program or the filesystem is sitting on isn't
ever leaving the confines of that machine. I just wanted a numerical answer
for IEEE 32 bit float versus 32 bit two's comp int (which I then investigated
using an exact arithmetic method).

K

#### Kenny McCormack

Kaz Kylheku said:
That can't happen because that program or the filesystem is sitting on isn't
ever leaving the confines of that machine. I just wanted a numerical answer
for IEEE 32 bit float versus 32 bit two's comp int (which I then investigated
using an exact arithmetic method).

You're pretty new to CLC, aren't you?

K

#### Kaz Kylheku

You're pretty new to CLC, aren't you?

You should feel silly saying that to someone who's been here since 1994 or

I remember Dan Pop, Tanmoy Bhattacharaya, Billy Chambless, ...

Just so you know:

1. I rule the roost around here.

(This decree expires on December 31st; send me an e-mail three weeks before
that to apply for an extension.)

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.

### Members online

No members online now.