On 26 August 2012 21:19, K. Frank <kfrank29.c@gmail.com> wrote:
Hello Dipanjan!

I don't know the answer to your specific question, but I offer a couple of
comments, and some perspective, below.

On Sun, Aug 26, 2012 at 9:10 AM, Dipanjan Das
<its.dipanjan.das@gmail.com> wrote:
> On 26 August 2012 17:42, Jan Ringoš <tringi@mx-3.cz> wrote:
>> ...
>> >>>>> ...
>> >>>>> * printf("%f\n",1);*
>> >>>>> ...
>> >>>>> Have you noticed the output from line #1 and #5? Code are same, but
>> >>>>> outputs
>> >>>>> How
>> >>>>> can
>> >>>>> this
>> >>>>> behavior be explained?
>> >>>>
>> >>>> You are writing code with undefined behavior, bad code is bad code,
>> >>>> ...

"Undefined behavior" is the short answer to your questions.  A legal, compliant
C compiler is allowed to do whatever it wants (that's what "undefined" means)
when confronted with your code.  A compiler might try to help you by detecting
the possibility that you made an error and issuing a warning, but it doesn't
have to.

(As an aside, in general the compiler can't detect this kind of error.  That is
most likely why the standard leaves it as undefined behavior.  Two things
about your line of code, printf("%f\n",1);:  First, printf is a function call so
in a straightforward compiler implementation, when the compiler compiles
that line of code, it doesn't know what the function printf is going to do with
its first argument, "%f\n", so it can't detect the error.  Of course, because
printf is a standard function, a more sophisticated compiler might, indeed,
know what printf does, but that would impose more work on the compiler
writers, something the standard elects not to do.  Second, and more
importantly, the first argument of printf can be the result of a computation.
In such a case the compiler simply cannot know at compile time what the
value of that argument might be at run time, so it can't detect the error in
the general case.  Of course, when the first argument of printf is a string
literal, a smart compiler is able to detect the error, but the standard does
not require it,)

>> >> ...
>> >> Your code is bad because it is undefined behavior, anything can happen,
>> >
>> > I am surprised at the point that if the behavior is inconsistent, how
>> > can
>> > MinGW and GCC procue consistently same o/p on each run?

Undefined behavior -- you shouldn't be surprised.

> ...
>> Your lines 1 and 3 print different result because, for ellipsis call,
>> floats
>> (converted to doubles) are passed on x87 pseudo-stack, not on *the* stack.
>> That is true for GCC/MinGW. So on line 1, you pushed the value onto the
>> stack, but printf reads from x87 stack, where there is nothing
>> (default-initialized to zeros). On your line 3, you repeat the situation,
>> but you get 1.0 because that value was placed on top of the x87 stack by
>> line 2.
>> But don't rely on it being this way.

Yup.  Can't rely on undefined behavior being this way.

>> ...
> Hello Jan,
> Here are few points which I don't understand:
> The term pseudo-stack is new to me. I am going to study how it works. In the
> mean time, can you please give me an one-liner regarding what it is.

I don't know what the pseudo-stack is either.  I also don't really care.
While I suppose that the question is technically on topic on a mingw
list ("Does mingw use a pseudo-stack, and, if so, what is it?"), my
guess is that this might not be the best list for such a discussion.
(Maybe a gcc list, or a list for compiler design.)  Most participants on
this list will tell you that undefined behavior may or may not cause a
pseudo-stack that may or may not exist to produce a result that may
or may not be the result expected by you.

> When statement #2 pushes the value onto x87 stack, doesn't it pop it off
> from it simultaneously while printing? Why a "stale" value is still
> available for statement #3?
> Consider the snippet below:
> #include <stdio.h>
> int main()
> {
> printf("6. %f\n",(float)9/5);
> printf("7. %f\n",1);
> }
> The output it produces is:
> 6. 1.800000
> 7. 1.799999
> While there is nothing wrong with #6, I surprise why the representation gets
> a little bit imprecise while it comes to #7. Following your logic, #6 pushes
> 1.8 as a 64bit double value onto x87 pseudo-stack. Statement #7, instead of
> pushing an integer 1 onto it, reads back from the x87 stack again. But, how
> many bits does it read out? The same 64 bits, isn't it? Then why does the
> value differ second time?
> ...

Well, again the short answer is "undefined behavior."  But the details of how
gcc / mingw happens to implement this particular bit of undefined behavior is
a legitimate and potentially interesting question (but maybe better addressed
to a gcc of compiler list), but one to which I do not know the answer.

If I wanted to find out the answer, I would look at the assembly language
produced by the compiler ("gcc -S"), and all would be revealed.

Here is what gcc -S produces. I am not familiar with few of the used opcodes. Hope it rings a bell to someone else.

.file "demo2.c"
.section .rodata
.string "6. %f\n"
.string "7. %f\n"
.globl main
.type main, @function
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
movl $.LC0, %eax
fldl .LC1
fstpl 4(%esp)
movl %eax, (%esp)
call printf
movl $.LC2, %eax
movl $1, 4(%esp)
movl %eax, (%esp)
call printf
.size main, .-main
.section .rodata
.align 8
.long -1073741824
.long 1073532108
.ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
.section .note.GNU-stack,"",@progbits

> Thanks & Regards,
> Dipanjan

Happy (Assembler) Hacking!

K. Frank

Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
MinGW-users mailing list

This list observes the Etiquette found at
We ask that you be polite and do the same.  Disregard for the list etiquette may cause your account to be moderated.

You may change your MinGW Account Options or unsubscribe at:
Also: mailto:mingw-users-request@lists.sourceforge.net?subject=unsubscribe


Thanks & Regards,